#例如:
class example(object):
def someFunction():
print("I am some function")
def __init__(self,x,y):
self.x = x
self.y = y
someFunction()
为什么此代码会生成someFunction未定义的错误? 是因为python的解释器在执行def someFunction 代码之前执行了def init 代码块吗?我认为python的执行顺序是自上而下的方法。任何见解都将不胜感激。
答案 0 :(得分:1)
您还需要在其前面添加self
:
def __init__(self,x,y):
self.x = x
self.y = y
self.someFunction()
答案 1 :(得分:0)
Andy Hayden的回答为您提供了必要的解决方案,但我认为您可能会欣赏一些专门针对您的问题的背景知识。请注意,这描述了所谓的" new"对象模型,虽然旧模型(从2.2天之前开始,仍然是Python 2中的默认模式,运行方式几乎相同)。
当解释器编译类时,读取整个类主体并将定义(在您的情况下,someFunction
和__init__
)保存在字典中。它构建了一个"基类列表" (它继承的类),然后它调用类的元类(除非你采取特殊的行动,在Python中你的类'元类将是内置类型{{ 1}})带有类名,基类列表和表示类的名称空间作为参数的字典。
在Python 3中,新模型是默认模型,您可以使用type
声明的关键字参数设置类的元类。这允许您验证我的断言。请考虑以下程序:
class
class print_args(type):
def __new__(cls, name, bases, name_space):
print("class:", cls)
print("Declaring class", name)
print("Bases:", bases)
print("Namespace:", name_space)
return type.__new__(cls, name, bases, name_space)
class A: pass
class B: pass
print("Defining C")
class C(A, B, metaclass=print_args):
CVar = "class attribute"
def myMethod(self, a):
return self.N, self.CVar
def __init__(self, N):
self.N = N
print("Creating c")
c = C(42)
print(c.CVar, C.CVar)
print(C.__dict__)
print(c.__dict__)
c.CVar = "instance attribute"
print(c.CVar, C.CVar)
print(c.__dict__)
类是一个简单的元类,它通过继承它来模仿print_args
的操作,并在打印一段时间后将实际工作委托给type
。声明type.__new__
类时,输出
C
请注意,当声明C类时,这一切都会发生 - 你可以通过下一行输出告诉它。另请注意,打印的值会告诉您传递给Defining C
class: <class '__main__.print_args'>
Declaring class C
Bases: (<class '__main__.A'>, <class '__main__.B'>)
Namespace: {'__qualname__': 'C', '__module__': '__main__', '__init__': <function C.__init__ at 0x10778bbf8>, 'myMethod': <function C.myMethod at 0x10778bc80>, 'CVar': 'class attribute'}
的内容。该程序接下来创建一个type.__new__
实例,并演示class属性也可以作为实例属性访问 - 方法解析顺序也应用于属性查找 - 实际上该实例也可以访问{{{已经有1}}和C
个类。
A
此时B
类的Creating c
class attribute class attribute
如下所示:
__dict__
并且其实例的字典如下所示:
C
它仅包含实例属性{'CVar': 'class attribute',
'__module__': '__main__',
'__doc__': None,
'__init__': <function C.__init__ at 0x10778bbf8>,
'myMethod': <function C.myMethod at 0x10778bc80>}
。但是在将值绑定到{'N': 42}
之后,我们可以看到实例属性现在与class属性不同。
N
通过对实例c.CVar
的更新了解来确认这一点。
instance attribute class attribute
希望这会让您更深入地了解声明类时会发生什么,以及实例和类是如何相关的。