如何在Python中访问类(静态)变量?

zysjyyx4  于 2022-11-26  发布在  Python
关注(0)|答案(6)|浏览(235)

如果我有下面的代码:

class Foo(object):
    bar = 1

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

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

xytpbqjk

xytpbqjk1#

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

n3schb8v

n3schb8v2#

定义类方法:

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
iqih9akk

iqih9akk3#

和所有好的例子一样,你已经简化了你实际上要做的事情。这很好,但是值得注意的是,当涉及到类和示例变量时,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方法!),或者在类本身中引用你的类名的想法对你来说似乎是错误的,请查看我链接的介绍。

x759pob2

x759pob24#

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

f = Foo() 
f.bah()
s3fp2yjn

s3fp2yjn5#

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

w8biq8rn

w8biq8rn6#

您可以通过对象访问类变量,也可以直接通过类名从类的外部或内部访问类变量,基本上,您应该直接通过类名访问类变量**,因为如果存在同名的类和示例变量相同名称的示例变量优先,而相同名称的示例变量在被对象访问时被忽略。因此,使用类名比使用对象访问类变量更安全。
例如,您可以从类别外部,依对象和直接依类别名称来存取类别变数,如下所示:

class Person:
    name = "John" # Class variable

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

输出量:

John
John

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

class Person:
    name = "John" # Class variable

obj = Person()
obj.name = "Tom" # Adds the same name instance variable as class variable
print(obj.name) # By object
print(Person.name) # By class name

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

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

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

当由对象访问时,相同名称的示例变量具有优先级:

Tom  # By object
John # By class name

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

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

obj = Person()
obj.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

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

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

class Person:
    name = "John" # Class variable
    
    def __init__(self, name):
        self.name = name # Adds 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

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

self访问相同名称的示例变量时,该变量具有优先级:

Tom  # By "self"
John # By class name

相关问题