为啥我不能在 python 中访问这个类成员?
Posted
技术标签:
【中文标题】为啥我不能在 python 中访问这个类成员?【英文标题】:Why can I not access this class member in python?为什么我不能在 python 中访问这个类成员? 【发布时间】:2011-01-11 08:49:20 【问题描述】:我有以下代码
class Transcription(object):
WORD = 0
PHONE = 1
STATE = 2
def __init__(self):
self.transcriptions = []
def align_transcription(self,model,target=Transcription.PHONE):
pass
这里的重要部分是我希望有一个类成员作为变量的默认值。然而,这会产生以下错误:
NameError: name 'Transcription' is not defined
为什么这是不可能的,什么是正确的(pythonic)方法来做这样的事情。
【问题讨论】:
正确的方法?很难说,你想做什么?为什么要将对象的类传递给该对象的函数?我看不出你想在这里做什么。 他想使用一个作用域为类的常量作为方法参数的默认值。 没错。我的错。语法着色使我蒙蔽了双眼。 :) 【参考方案1】:您无法访问它,因为在 def
语句运行时未定义 Transcription
。
def align_transcription(self,model,target=PHONE):
pass
会成功的。 PHONE
名称在命名空间中可用,在class
语句完成执行后将成为Transcription
类。
其工作方式是class
是一个实际运行的语句。当 Python 遇到一个类语句时,它会进入一个新的本地范围并执行在 class
语句下缩进的所有内容,就好像它是一个函数一样。然后它将生成的命名空间、类的名称和基类的元组传递给 metaclass,默认情况下为 type
。元类返回一个自身的实例,它是实际的类。当def
语句执行时,这些都没有发生。
声明
class Foo(object):
a = 1
def foo(self):
print self.a
创建一个命名空间ns = 'a': 1, 'foo': foo
然后执行
Foo = type('Foo', (object,), ns)
这相当于
def foo(self):
print self.a
Foo = type('Foo', (object,), 'a': 1, 'foo': foo)
您可以清楚地看到在定义 foo
时未定义 Foo
,因此 Foo.a
没有意义。
【讨论】:
【参考方案2】:直到定义结束,类才与其名称相关联。
我写这个的方式(我不能保证它是 Pythonic)是:
class Transcription(object):
WORD = 1 # zero won't work below... need to change the value
PHONE = 2
STATE = 3
def align_transcription(self, model, target=None):
target = target or Transcription.PHONE
# or
if target is None: target = Transcription.PHONE
或者,将PHONE
设置为零而不是WORD
也可以。无论常量的值如何,if
语句都将起作用,但or
将用PHONE
替换零值。
其他选项是在另一个类中定义常量或在类外绑定align_transcription
方法:
class Transcription(object):
WORD = 0
PHONE = 1
STATE = 2
def _unbound_align_transcription(self, model, target=Transcription.PHONE):
pass
Transcription.align_transcription = _unbound_align_transcription
【讨论】:
或者像***.com/questions/4655745/…那样做......我知道,只是没有立即想到。 我认为像“类对象在其定义完成之前不可用”这样的简单响应也可以。 这是真的,除了在类are
中定义的值可用。诀窍是绑定函数 signatures (def
行)在定义点位于类范围内,而绑定函数 code 不在,需要使用要消除歧义的类名。【参考方案3】:
定义 align_transcription 方法时 Transaction 类还不存在,但 PHONE 在范围内可用。 所以,你可以这样做:
class Transcription(object):
WORD = 0
PHONE = 1
STATE = 2
def __init__(self):
self.transcriptions = []
def align_transcription(self,model,target=PHONE):
pass
如果您打算在子类或实例中覆盖 PHONE,则使用 target=None 默认值:
def align_transcription(self,model,target=None):
if target is None:
target = self.PHONE
【讨论】:
以上是关于为啥我不能在 python 中访问这个类成员?的主要内容,如果未能解决你的问题,请参考以下文章