如何设置和访问类的属性?
假设我有这段代码:
class Example(object):
def the_example(self):
itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
当我尝试运行时,出现了一个错误,提示内容是:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'Example' object has no attribute 'itsProblem'
我该如何访问这个属性呢?我试着添加了另一个方法来返回它:
def return_itsProblem(self):
return itsProblem
但是问题还是没有解决。
5 个回答
如果你有一个实例函数(也就是一个会传入self的函数),你可以用self来获取这个类的引用,方法是使用self.__class__
。
比如在下面的代码中,tornado创建了一个实例来处理get请求,但我们可以获取到get_handler
这个类,并用它来保存一个riak客户端,这样我们就不需要为每个请求都创建一个新的客户端了。
import tornado.web
import riak
class get_handler(tornado.web.requestHandler):
riak_client = None
def post(self):
cls = self.__class__
if cls.riak_client is None:
cls.riak_client = riak.RiakClient(pb_port=8087, protocol='pbc')
# Additional code to send response to the request ...
你现在声明的是一个局部变量,而不是一个类变量。如果你想设置一个实例变量(属性),可以使用
class Example(object):
def the_example(self):
self.itsProblem = "problem" # <-- remember the 'self.'
theExample = Example()
theExample.the_example()
print(theExample.itsProblem)
如果你想设置一个类变量(也叫静态成员),可以使用
class Example(object):
def the_example(self):
Example.itsProblem = "problem"
# or, type(self).itsProblem = "problem"
# depending what you want to do when the class is derived.
简单来说,答案是
在你的例子中,itsProblem
是一个局部变量。
你必须使用 self
来设置和获取实例变量。你可以在 __init__
方法中进行设置。这样你的代码就会是:
class Example(object):
def __init__(self):
self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
但是如果你想要一个真正的类变量,那就直接使用类名:
class Example(object):
itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
print (Example.itsProblem)
不过要小心,因为 theExample.itsProblem
会自动被设置为等于 Example.itsProblem
,但它们并不是同一个变量,可以独立改变。
一些解释
在 Python 中,变量可以动态创建。因此,你可以这样做:
class Example(object):
pass
Example.itsProblem = "problem"
e = Example()
e.itsSecondProblem = "problem"
print Example.itsProblem == e.itsSecondProblem
这会打印出
True
所以,这正是你在之前例子中所做的。
实际上,在 Python 中,我们用 self
来表示 this
,但它的含义稍微多一点。self
是任何对象方法的第一个参数,因为第一个参数总是对象的引用。这是自动的,无论你叫它 self
还是其他名字。
这意味着你可以这样做:
class Example(object):
def __init__(self):
self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
或者:
class Example(object):
def __init__(my_super_self):
my_super_self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
这完全是一样的。任何对象方法的第一个参数都是当前对象,我们只是约定叫它 self
。 你可以像在外部一样,给这个对象添加一个变量。
现在,关于类变量。
当你这样做:
class Example(object):
itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
你会注意到我们首先设置了一个类变量,然后访问一个对象(实例)变量。我们从未设置这个对象变量,但它仍然可以工作,这是怎么回事呢?
其实,Python 首先会尝试获取对象变量,但如果找不到,就会给你类变量。注意:类变量在实例之间是共享的,而对象变量则不是。
总结一下,永远不要用类变量来设置对象变量的默认值。要使用 __init__
来做到这一点。
最终,你会了解到 Python 类本身也是实例,因此它们也是对象,这会让你更好地理解上述内容。等你明白这一点后,再回来看看这个内容吧。