如果我有以下代码:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
它抱怨
未定义全局名称“bar”
我如何访问类/静态变量栏内的方法bah?
如果我有以下代码:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
它抱怨
未定义全局名称“bar”
我如何访问类/静态变量栏内的方法bah?
与所有好的示例一样,您已经简化了实际要做的事情。这很好,但值得注意的是,当涉及到类变量和实例变量时,python有很大的灵活性。方法也是如此。我推荐阅读Michael Fötsch的new-style类介绍,特别是第2到6节。
在开始学习时需要花很多功夫记住的一件事是python不是java。这不仅仅是陈词滥调。在java中,编译整个类,使得名称空间解析非常简单:在方法外部(任何地方)声明的任何变量都是实例变量(如果是静态的,则是类变量),并且可以在方法内隐式访问。
在python中,最重要的经验法则是依次搜索三个名称空间来查找变量:
函数/方法 当前模块 内置命令
{开始教育学}
但也有有限的例外。我想到的主要问题是,当装入类定义时,类定义是它自己的隐式名称空间。但这只在模块被加载时持续,并且在方法中完全被绕过。因此:
>>> class A(object):
foo = 'foo'
bar = foo
>>> A.foo
'foo'
>>> A.bar
'foo'
but:
>>> 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
{结束教育学}
In the end, the thing to remember is that you do have access to any of the variables you want to access, but probably not implicitly. If your goals are simple and straightforward, then going for Foo.bar or self.bar will probably be sufficient. If your example is getting more complicated, or you want to do fancy things like inheritance (you can inherit static/class methods!), or the idea of referring to the name of your class within the class itself seems wrong to you, check out the intro I linked.
定义类方法:
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
你可以通过对象访问类变量,也可以从类外部或类内部直接通过类名访问类变量,基本上,你应该直接通过类名访问类变量,因为如果有相同名称的类和实例变量,相同名称的实例变量将被优先考虑,而相同名称的实例变量在被对象访问时被忽略。因此,使用类名比使用对象访问类变量更安全。
例如,你可以通过对象访问类变量,也可以直接从类外部通过类名访问类变量,如下所示:
class Person:
name = "John" # Class variable
obj = Person()
print(obj.name) # By object
print(Person.name) # By class name
输出:
John
John
但是,如果你通过object添加了与类变量相同的name实例变量:
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添加与类变量相同的name实例变量:
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
当被object访问时,相同名称的实例变量将被优先排序:
Tom # By object
John # By class name
并且,你也可以通过self和直接通过类名从实例方法内部访问类变量,如下所示:
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
但是,如果你通过object添加了与类变量相同的name实例变量:
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添加与类变量相同的name实例变量:
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