在类的构造函数中,我看到在没有初始化的情况下使用了一些自变量。例如:
def __init__(self, x):
self.x = x + self.y
在上面的示例中,如您所见,self.y
未经初始化即被使用。我的假设是这个领域的价值来自超级班。
悬停,在超类中我也看不到self.y
的定义。那么,哪里可以来自?
ADDED
我需要补充的是,此字段也未定义为“类属性”。所以,我有这样的事情:
class MyClass(SomeBaseClass):
def __init__(self, x, y):
self.aaa = self.bbb + self.ccc
# some other code
已添加2
检查时我做了以下事情:
class MyClass(SomeBaseClass):
def __init__(self, x, y):
print(self.__dict__) # <--- please notice this line !!!!!!!!!
self.aaa = self.bbb + self.ccc
# some other code
因此,我看到一个包含键和值的字典。所以,我的假设是这些值来自基类。但是,如果我转到基类,并将打印添加到构造函数
def __init__(self, x, y, z):
print('some additional print in the beginning')
# some code here
print('print at the end of the constructor')
然后我没有看到这些打印(好像没有执行基类的构造函数)。
答案 0 :(得分:1)
如果self.y
之前没有分配__init__
,那么这只能是class-attribute
(可能是继承的)。 self
通常表示某个类的实例,但instance-attributes
中的init()
首先是 init 。如果它不存在,那么此时它不是instance-attribute
。
示例:
class test :
y = 7 # scope: class
def __init__( self ):
self.x = self.y + 1 # scope: instance
a = test()
a.x # 8 # scope: instance
a.y # 7 # scope: instance, pulled from class
test.y # 7 # scope: class
对于你的研究:In Python, it’s all about the attributes
(关于类和实例属性之间差异的最佳解释,我到目前为止发现)
答案 1 :(得分:1)
如果覆盖 init ,则不会执行基类的 init 方法。您必须在 init 中明确调用super()。 init ()来执行此操作。如果要查找用于查找实例属性的类,请执行以下操作:MyClass.mro()
。据我所知,您将获得__getattribute__
从左到右搜索的列表。
答案 2 :(得分:1)
我在类的构造函数中有一些self.*
属性,它们可以来自父类(超类)或子类。
如果未从所考虑的类的构造函数调用super().__init__()
,则尚未实现在父类的构造函数中完成的定义。因此,该属性不能来自父类。
还可能发生的是,某些子类在其构造函数中创建了一些定义(例如,已经引入了一些属性),然后调用其父类的构造函数(这意味着调用了类的构造函数)。在这种情况下,您的类将看到子类中定义的属性。它们将被视为自己的属性。
例如:
class your_class():
def __init__(self):
print self.x # How can we print self.x if it does not exist?
class child_class():
def __init__(self, x):
self.x = x
super().__init__() # here is constructor of the parent class (your_class) is called and this constructor will see self.x defined here.