首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我不能在python中访问这个类成员?

为什么我不能在python中访问这个类成员?
EN

Stack Overflow用户
提问于 2011-01-11 16:49:21
回答 3查看 473关注 0票数 3

我有以下代码

代码语言:javascript
复制
class Transcription(object):
    WORD = 0
    PHONE = 1
    STATE = 2

    def __init__(self):
        self.transcriptions = []

    def align_transcription(self,model,target=Transcription.PHONE):
        pass

这里最重要的部分是,我希望有一个类成员作为变量的默认值。但是,这会产生以下错误:

代码语言:javascript
复制
NameError: name 'Transcription' is not defined

为什么这是不可能的,什么是正确的(pythonic)方式来做这样的事情。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-01-11 16:52:24

您不能访问它,因为在运行def语句时没有定义Transcription

代码语言:javascript
复制
 def align_transcription(self,model,target=PHONE):
        pass

就能达到目的。PHONE名称在名称空间中可用,在class语句执行完成后,该名称空间将成为Transcription类。

它的工作方式是class是一个实际运行的语句。当Python遇到class语句时,它会进入一个新的局部作用域,并执行在class语句下缩进的所有内容,就好像它是一个函数一样。然后,它将生成的命名空间、类名和基类的元组传递给元类,默认情况下元类是type。元类返回它自己的一个实例,它是实际的类。当def语句执行时,所有这些都不会发生。

这句话

代码语言:javascript
复制
class Foo(object):
    a = 1
    def foo(self):
        print self.a

创建命名空间ns = {'a': 1, 'foo': foo},然后执行

代码语言:javascript
复制
Foo = type('Foo', (object,), ns)

这相当于

代码语言:javascript
复制
def foo(self):
    print self.a

Foo = type('Foo', (object,), {'a': 1, 'foo': foo})

您可以清楚地看到,在定义foo时没有定义Foo,因此Foo.a没有任何意义。

票数 11
EN

Stack Overflow用户

发布于 2011-01-11 16:58:40

直到定义结束,类才与其名称相关联。

我写这篇文章的方式(我不能保证它是Pythonic式的)是:

代码语言:javascript
复制
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设置为0而不是WORD也可以。无论常量的值是多少,if语句都会起作用,但是or会用PHONE替换零值。

其他选项是在另一个类中定义常量,或者在类外部绑定align_transcription方法:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2011-01-11 16:57:04

当您定义align_transcription方法时,Transaction类还不存在,但PHONE在作用域中可用。因此,您可以使用以下两种方法之一:

代码语言:javascript
复制
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默认值:

代码语言:javascript
复制
def align_transcription(self,model,target=None):
    if target is None:
        target = self.PHONE
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4655745

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档