如果我有以下代码:

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)
            
f = Foo()
f.bah()

它抱怨

未定义全局名称“bar”

我如何访问类/静态变量栏内的方法bah?


当前回答

与所有好的示例一样,您已经简化了实际要做的事情。这很好,但值得注意的是,当涉及到类变量和实例变量时,python有很大的灵活性。方法也是如此。我推荐阅读Michael Fötsch的new-style类介绍,特别是第2到6节。

在开始学习时需要花很多功夫记住的一件事是python不是java。这不仅仅是陈词滥调。在java中,编译整个类,使得名称空间解析非常简单:在方法外部(任何地方)声明的任何变量都是实例变量(如果是静态的,则是类变量),并且可以在方法内隐式访问。

在python中,最重要的经验法则是依次搜索三个名称空间来查找变量:

函数/方法 当前模块 内置命令

{开始教育学}

但也有有限的例外。我想到的主要问题是,当装入类定义时,类定义是它自己的隐式名称空间。但这只在模块被加载时持续,并且在方法中完全被绕过。因此:

>>> class A(object):
        foo = 'foo'
        bar = foo


>>> A.foo
'foo'
>>> A.bar
'foo'

but:

>>> class B(object):
        foo = 'foo'
        def get_foo():
            return foo
        bar = get_foo()



Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    class B(object):
  File "<pyshell#11>", line 5, in B
    bar = get_foo()
  File "<pyshell#11>", line 4, in get_foo
    return foo
NameError: global name 'foo' is not defined

{结束教育学}

In the end, the thing to remember is that you do have access to any of the variables you want to access, but probably not implicitly. If your goals are simple and straightforward, then going for Foo.bar or self.bar will probably be sufficient. If your example is getting more complicated, or you want to do fancy things like inheritance (you can inherit static/class methods!), or the idea of referring to the name of your class within the class itself seems wrong to you, check out the intro I linked.

其他回答

bar是你的静态变量,你可以使用Foo.bar访问它。

基本上,你需要用Class name限定你的静态变量。

class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()

定义类方法:

class Foo(object):
    bar = 1
    @classmethod
    def bah(cls):    
        print cls.bar

现在如果bah()必须是实例方法(即有访问self的权限),你仍然可以直接访问类变量。

class Foo(object):
    bar = 1
    def bah(self):    
        print self.bar

与所有好的示例一样,您已经简化了实际要做的事情。这很好,但值得注意的是,当涉及到类变量和实例变量时,python有很大的灵活性。方法也是如此。我推荐阅读Michael Fötsch的new-style类介绍,特别是第2到6节。

在开始学习时需要花很多功夫记住的一件事是python不是java。这不仅仅是陈词滥调。在java中,编译整个类,使得名称空间解析非常简单:在方法外部(任何地方)声明的任何变量都是实例变量(如果是静态的,则是类变量),并且可以在方法内隐式访问。

在python中,最重要的经验法则是依次搜索三个名称空间来查找变量:

函数/方法 当前模块 内置命令

{开始教育学}

但也有有限的例外。我想到的主要问题是,当装入类定义时,类定义是它自己的隐式名称空间。但这只在模块被加载时持续,并且在方法中完全被绕过。因此:

>>> class A(object):
        foo = 'foo'
        bar = foo


>>> A.foo
'foo'
>>> A.bar
'foo'

but:

>>> class B(object):
        foo = 'foo'
        def get_foo():
            return foo
        bar = get_foo()



Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    class B(object):
  File "<pyshell#11>", line 5, in B
    bar = get_foo()
  File "<pyshell#11>", line 4, in get_foo
    return foo
NameError: global name 'foo' is not defined

{结束教育学}

In the end, the thing to remember is that you do have access to any of the variables you want to access, but probably not implicitly. If your goals are simple and straightforward, then going for Foo.bar or self.bar will probably be sufficient. If your example is getting more complicated, or you want to do fancy things like inheritance (you can inherit static/class methods!), or the idea of referring to the name of your class within the class itself seems wrong to you, check out the intro I linked.

而不是酒吧使用自我。bar或Foo.bar。赋值给Foo。Bar将创建一个静态变量,并分配给self。Bar将创建一个实例变量。