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

时间:2009-04-01 21:23:40

标签: python

如果我有以下python代码:

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)

f = Foo()
f.bah()

抱怨

NameError: global name 'bar' is not defined

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

6 个答案:

答案 0 :(得分:128)

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

答案 1 :(得分:66)

定义类方法:

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

答案 2 :(得分:11)

与所有好的例子一样,您已经简化了实际尝试的内容。这很好,但值得注意的是,当涉及到类和实例变量时,python具有很多的灵活性。方法也是如此。有关可能性的清单,我建议您阅读Michael Fötsch' new-style classes introduction,尤其是第2至第6部分。

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

使用python,最重要的经验法则是按顺序搜索三个名称空间:

  1. 功能/方法
  2. 当前模块
  3. 内置命令
  4. {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}

    最后,要记住的是你可以访问你想要访问的任何变量,但可能不是隐式的。如果你的目标简单明了,那么去Foo.bar或self.bar可能就足够了。如果你的例子变得越来越复杂,或者你想做继承等花哨的东西(你可以继承静态/类方法!),或者在类中引用你的类名称的想法本身似乎不对,请查看介绍我联系。

答案 3 :(得分:8)

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

f = Foo() 
f.bah()

答案 4 :(得分:-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()

答案 5 :(得分:-3)

record Book { public string Name { get; set; } } static void Main() { List<Book> books1 = new List<Book>() { new Book { Name = "Book1.1" }, new Book { Name = "Book1.2" }, new Book { Name = "Book1.3" } }; var books2 = books1.Select(b => b with { }).ToList(); books2[0].Name = "Changed"; books2[1].Name = "Changed"; Console.WriteLine("Books1 contains:"); foreach (var item in books1) { Console.WriteLine(item); } Console.WriteLine("Books2 contains:"); foreach (var item in books2) { Console.WriteLine(item); } } 是您的静态变量,您可以使用 bar 访问它。

基本上,您需要使用类名来限定静态变量。