Python 哪个类拥有方法和属性
假设我们有以下代码:Python 哪个类拥有方法和属性,python,inheritance,attributes,self,Python,Inheritance,Attributes,Self,假设我们有以下代码: class C(CC): a = 1 b = 2 def __init__(self): self.x = None self.y = 1 如何在Python中快速找到属性或方法的定义位置?如果它属于祖先类,或者它是类C的方法。您可以看到属性a、b、x、y。它们必须属于C类吗?或者它们可以来自祖先类?何时将类型指定给变量 为什么不用呢 class C(CC): a = 1 b = 2 x = None y = 1 class
class C(CC):
a = 1
b = 2
def __init__(self):
self.x = None
self.y = 1
如何在Python中快速找到属性或方法的定义位置?如果它属于祖先类,或者它是类C的方法。您可以看到属性a、b、x、y
。它们必须属于C类吗?或者它们可以来自祖先类?何时将类型指定给变量
为什么不用呢
class C(CC):
a = 1
b = 2
x = None
y = 1
class C(CC):
a = 1
b = 2
x = None
y = 1
谢谢在第一个示例中,
a
和b
是C类对象的属性。(考虑“静态”属性。)和x
和y
是C实例的属性。(因此,常规实例属性。)
在第二个示例中,所有四个都是C的属性,而不是它的实例的属性
在Python中,您不能“声明”由特定类定义的属性,这意味着没有要继承的属性定义。(或多或少,但我不打算通过引入\uuuuuuuuuuuuuuuuuuuuuuuuu
来搅乱局面)。您可以通过搜索“def method_name(”)来查找方法定义,方法定义与大多数OO语言一样是继承的
令人困惑的是,您可以通过类的实例访问类属性,然后如果为该属性指定新值,则会创建一个新的实例属性:
In [1]: class C(object): a=1
In [2]: c1 = C()
In [3]: c1.a
Out[3]: 1
In [5]: c1.__dict__
Out[5]: {}
In [6]: c1.a=2
In [7]: c1.__dict__
Out[7]: {'a': 2}
In [8]: c2 = C()
In [9]: c2.a
Out[9]: 1
它允许您使用类属性为实例属性提供默认值。但我不认为这是一件非常常见的事情–我倾向于使用默认值作为
\uuuu init\uuuu()
参数。在第一个示例中,a
和b
是C类对象的属性。(想想“静态”属性。)和x
和y
是C实例的属性(因此,常规实例属性)
在第二个示例中,所有四个都是C的属性,而不是它的实例的属性
在Python中,您不能“声明”由特定类定义的属性,这意味着没有要继承的属性定义(或多或少,但我不会通过引入\uuuuuu slots\uuuu
)来混淆视听。您可以通过搜索“def method\u name(”和大多数OO语言一样,方法定义是继承的
令人困惑的是,您可以通过类的实例访问类属性,然后如果为该属性指定新值,则会创建一个新的实例属性:
In [1]: class C(object): a=1
In [2]: c1 = C()
In [3]: c1.a
Out[3]: 1
In [5]: c1.__dict__
Out[5]: {}
In [6]: c1.a=2
In [7]: c1.__dict__
Out[7]: {'a': 2}
In [8]: c2 = C()
In [9]: c2.a
Out[9]: 1
它允许您使用类属性为实例属性提供默认值。但我不认为这是一件非常常见的事情–我倾向于使用默认值作为\uuuu init\uuuuuuuuuuuuo()
参数。为什么不使用默认值呢
class C(CC):
a = 1
b = 2
x = None
y = 1
class C(CC):
a = 1
b = 2
x = None
y = 1
这不是同一件事。它有四个类级属性,由类C
的所有对象共享
class C(CC):
a = 1
b = 2
def __init__(self):
self.x = None
self.y = 1
这是不同的。它有两个类级属性,由类C
的所有对象共享,两个实例变量对类C
的每个对象都是唯一的
class C(CC):
a = 1
b = 2
def __init__(self):
self.x = None
self.y = 1
您的两个代码示例非常不同。它们无法进行比较
为了回答您的另一个问题,我们使用GREP和其他工具来搜索源代码。这很简单。为什么不使用GREP和其他工具呢
class C(CC):
a = 1
b = 2
x = None
y = 1
class C(CC):
a = 1
b = 2
x = None
y = 1
这不是同一件事。它有四个类级属性,由类C
的所有对象共享
class C(CC):
a = 1
b = 2
def __init__(self):
self.x = None
self.y = 1
这是不同的。它有两个类级属性,由类C
的所有对象共享,两个实例变量对类C
的每个对象都是唯一的
class C(CC):
a = 1
b = 2
def __init__(self):
self.x = None
self.y = 1
您的两个代码示例非常不同。它们无法进行比较
为了回答你的另一个问题,我们使用GREP和其他工具来搜索源代码。这很简单。那么你可以变得更有趣:
C.a=3
;然后c1.a==2
,因为它是它自己的实例变量,c2.a==3
,因为它是在原型链中查找回类的。稍后我将n其他函数是对self.x.someMethod()
的调用,因此x可能是某个对象,但在什么地方定义了x实际是什么?在某个继承类中?或者它可以是什么?你说“令人困惑”,但我从未发现它是这样的(即使在我第一次接触Python时)。这纯粹是一个原型链。只要你在实例中设置了一个值,它就在实例中设置了,就是这样。@xralf:x
可以在任何地方定义。我的意思是在任何地方。c4=C();c4.x=Q()。它通常更可能被定义在类或超类中,但它不是必需的。因为一些原因,我觉得它很混乱。一个是Python有一个基于类的对象模型,所以你不希望一个原型链用于数据。另一个是行为不同于C++ <代码>静态< /COD>及其DES。另一个原因是,我期望对象的“数据”在其\uuuuu dict\uuuuu
/\uuuuuuu slots\uuuuuu
中(期望和/或想要,例如自动预打印数据),因此它可以(理论上)甚至对于不依赖该行为的Python用户也不例外。我知道该行为在Python元模型的上下文中是如何有意义和必要的,但我不喜欢它用于数据。然后你会变得更有趣:C.a=3
;然后c1.a==2
,因为它是它自己的实例变量,c2.a==3
它在原型链中找到了类。后来在其他函数中调用了self.x.someMethod()
,因此x可能是某个对象,但在哪里定义了x实际是什么?在某个继承类中?或者它可以是什么?你说“令人困惑”,但我从未发现它是这样的(即使在我第一次接触Python时)。这纯粹是一个原型链。只要你在实例中设置了一个值,它就在实例中设置了,就是这样。@xralf:x
可以在任何地方定义。我的意思是在任何地方。c4=C();c4.x=Q()
。它通常更可能在