在Python中,如何在类方法中访问“静态”类变量

问题描述 投票:139回答:5

如果我有以下python代码:

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)

f = Foo()
f.bah()

抱怨

NameError: global name 'bar' is not defined

如何在方法bar中访问类/静态变量bah

python
5个回答
140
投票

代替bar使用self.barFoo.bar。分配给Foo.bar将创建一个静态变量,分配给self.bar将创建一个实例变量。


73
投票

定义类方法:

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

11
投票

与所有好的示例一样,您已经简化了实际要执行的操作。这很好,但值得注意的是,在类变量和实例变量之间,python具有lot的灵活性。方法也可以这样说。有关可能的详细列表,建议阅读Michael Fötsch' new-style classes introduction,尤其是第2至6节。

开始时需要记住很多事情的事情是python不是java。不仅仅是陈词滥调。在Java中,整个类都会被编译,使名称空间解析真正简单:方法(在任何地方)声明的任何变量都是实例(或者,如果是静态的,则是类)变量,并且可以在方法内隐式访问。

使用python,一般的经验法则是,依次搜索三个名称空间以查找变量:

  1. 功能/方法
  2. 当前模块
  3. 公告

{begin pedagogy}

仅有少数例外。我主要想到的是,在加载类定义时,该类定义是其自己的隐式命名空间。但这仅在模块被加载时才持续,并且在方法内时将被完全忽略。因此:

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


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

但是:

>>> 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

{end pedagogy}

最后,要记住的事情是您do可以访问要访问的任何变量,但可能不是隐式的。如果您的目标简单明了,那么选择Foo.bar或self.bar可能就足够了。如果您的示例变得越来越复杂,或者您想做一些像继承的事情(可以继承静态/类方法!),或者在类本身中引用类名的想法对您来说是错误的,请查看我链接的简介。


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

f = Foo() 
f.bah()

-1
投票
class Foo(object) :

          bar = 1

          def bah(object_reference) :

                 object_reference.var=Foo.bar

                 return object_reference.var

f = Foo() 

print 'var=', f.bah()
© www.soinside.com 2019 - 2024. All rights reserved.