如何在Python中访问“静态”类变量?

cgyqldqp  于 2022-11-19  发布在  Python
关注(0)|答案(6)|浏览(173)

如果我有下面的代码:

class Foo(object):
    bar = 1

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

它抱怨
NameError:未定义全局名称“bar”
如何访问类/静态变量bar

eeq64g8w

eeq64g8w1#

使用self.barFoo.bar代替bar。赋值给Foo.bar将创建一个静态变量,赋值给self.bar将创建一个示例变量。

mcvgt66p

mcvgt66p2#

定义类方法:

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
gdx19jrr

gdx19jrr3#

和所有好的例子一样,你已经简化了你实际上要做的事情。这很好,但是值得注意的是,当涉及到类和示例变量时,python有 * 很多 * 的灵活性。同样的话,方法也是如此。为了得到一个好的可能性列表,我推荐阅读Michael Fötsch' new-style classes introduction,特别是第2到6节。
有一件事在开始使用时需要做很多工作才能记住,**python不是java。**不仅仅是陈词滥调。在java中,编译整个类,使命名空间解析变得真实的简单:任何在方法外声明的变量(任何地方)都是示例(或者,如果是静态的,则是类)变量,并且可以在方法内隐式访问。
对于python,主要的经验法则是在三个名称空间中按顺序搜索变量:
1.功能/方法
1.当前模块
1.内建
{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可能就足够了。如果您的示例变得越来越复杂,或者您想做一些像继承这样的花哨的事情(你可以继承static/class方法!),或者在类本身中引用你的类名的想法对你来说似乎是错误的,请查看我链接的介绍。

exdqitrt

exdqitrt4#

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

f = Foo() 
f.bah()
cyvaqqii

cyvaqqii5#

bar是静态变量,可以使用Foo.bar访问它。
基本上,您需要使用类名来限定静态变量。

ru9i0ody

ru9i0ody6#

你可以通过对象访问类变量,也可以直接通过类名从类的外部或内部访问类变量,基本上,你应该直接通过类名访问类变量,因为这比通过对象**访问它们更安全。
例如,您可以从类别外部,依对象和直接依类别名称来存取类别变数,如下所示:

class Person:
    name = "John" # Class variable

p = Person()
print(p.name) # By object
print(Person.name) # By class name

输出量:

John
John

但是,如果您通过对象添加与类变量同名的示例变量:

class Person:
    name = "John" # Class variable

p = Person()
p.name = "Tom" # The same name instance variable as class variable
print(p.name) # By object
print(Person.name) # By class name

或者,如果在__init__()中添加与类变量self同名的示例变量:

class Person:
    name = "John" # Class variable
    
    def __init__(self, name):
        self.name = name # The same name instance variable as class variable

p = Person("Tom")
print(p.name) # By object
print(Person.name) # By class name

在此对象访问情况下,相同名称的示例变量具有优先级:

Tom  # Object accessing
John # Class name accessing

而且,您还可以通过self和直接通过类名从示例方法内部访问class变量,如下所示:

class Person:
    name = "John" # Class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # By class name

p = Person()
p.test()

输出量:

John
John

但是,如果您通过对象添加与类变量同名的示例变量:

class Person:
    name = "John" # Class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # By class name

p = Person()
p.name = "Tom" # The same name instance variable as the class variable
p.test()

或者,如果在__init__()中添加与类变量self同名的示例变量:

class Person:
    name = "John" # Class variable
    
    def __init__(self, name):
        self.name = name # The same name instance variable as the class variable
        
    def test(self): # Instance method
        print(self.name) # By "self"
        print(Person.name) # Directly by class name

p = Person("Tom")
p.test()

self访问的情况下,相同名称的示例变量优先:

Tom  # "self" accessing
John # Class name accessing

相关问题