如何设置和访问类的属性?

104 投票
5 回答
308850 浏览
提问于 2025-04-16 02:29

假设我有这段代码:

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 个回答

10

如果你有一个实例函数(也就是一个会传入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 ...
    
14

你现在声明的是一个局部变量,而不是一个类变量。如果你想设置一个实例变量(属性),可以使用

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.
183

简单来说,答案是

在你的例子中,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 类本身也是实例,因此它们也是对象,这会让你更好地理解上述内容。等你明白这一点后,再回来看看这个内容吧。

撰写回答