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

In Python how can I access “static” class variables within class methods

如果我有以下python代码:

1
2
3
4
5
6
7
8
class Foo(object):
    bar = 1

    def bah(self):
        print(bar)

f = Foo()
f.bah()

它抱怨

1
NameError: global name 'bar' is not defined

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


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


定义类方法:

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

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

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


和所有好的例子一样,您已经简化了您实际要做的事情。这很好,但值得注意的是,当涉及到类与实例变量时,Python具有很大的灵活性。方法也是如此。关于一个很好的可能性列表,我建议你读迈克尔F?TSCH的新型课程介绍,特别是第2至6节。

一开始需要记住很多工作的是Python不是Java。不仅仅是陈词滥调。在Java中,编译整个类,使得命名空间解析非常简单:在方法(任何地方)之外声明的任何变量都是实例(或者,如果是静态的、类的)变量,并且在方法中是隐式访问的。

对于python,最重要的经验是有三个名称空间按顺序搜索变量:

  • 功能/方法
  • 当前模块
  • 建筑材料
  • {begin pedagogy}

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> class A(object):
            foo = 'foo'
            bar = foo


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

    但是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    >>> 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}

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


    1
    2
    3
    4
    5
    6
    7
    class Foo(object):
         bar = 1
         def bah(self):
             print Foo.bar

    f = Foo()
    f.bah()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Foo(object) :

              bar = 1

              def bah(object_reference) :

                     object_reference.var=Foo.bar

                     return object_reference.var

    f = Foo()

    print 'var=', f.bah()