3

我有一个 Python 类

class pytest:
    i = 34
    def func(self):
        return "hello world"

当我访问时pytest.i,我得到 34。我也可以用另一种方式做到这一点:

a = pytest()
a.i

这也给出了 34。

如果我尝试访问 (non-existing) pytest.j,我会得到

Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
pytest.j
AttributeError: class pytest has no attribute 'j'

当我尝试时a.j,错误是

Traceback (most recent call last):
File "<pyshell#8>", line 1, in <module>
a.j
AttributeError: pytest instance has no attribute 'j'

所以我的问题是:这两种情况到底发生了什么,有什么区别?

4

2 回答 2

7

不,这是两个不同的东西。

在 Python 中,一切都是对象。类是对象,函数是对象,实例是对象。因为一切都是对象,所以一切都以类似的方式表现。在您的情况下,您创建一个名为“pytest”的类实例(== 一个类型为“Class”的对象)。该对象有两个属性:ifuci是“Integer”或“Number”fuc的一个实例,是“Function”的一个实例。

当你使用“pytest.j”时,你告诉python“查找对象pytest,当你拥有它时,查找i”。“pytest”是一个类实例,但这并不重要。

当您创建“pytest”的实例(== 类型为“pytest”的对象)时,您将拥有一个具有“默认值”的对象。在您的情况下,a是一个实例,pytest这意味着找不到的任何内容都a将在pytest, next 中搜索。

所以的a.j意思是:“看进去a。当它不存在时,也看进去pytest”。但是j不存在,Python 现在必须给你一个有意义的错误信息。它可以说“类pytest没有属性'j'”。这将是正确但毫无意义的:您必须弄清楚自己试图j通过a. 这会令人困惑。圭多不会有那个。

因此,python 使用了不同的错误信息。由于它并不总是具有实例的名称 ( a),因此设计者决定改用该类型,因此您会得到“pytest instance...”。

于 2009-08-20T09:01:01.120 回答
0

总而言之,有两种类型的变量与类和对象相关联:类变量和实例变量。类变量与类相关联,但实例变量与对象相关联。这是一个例子:

class TestClass:
    classVar = 0
    def __init__(self):
        self.instanceVar = 0

classVar 是与类 TestClass 关联的类变量。instanceVar 是与 TestClass 类型的对象关联的实例变量。

print(TestClass.classVar) # prints 0
instance1 = TestClass() # creates new instance of TestClass
instance2 = TestClass() # creates another new instance of TestClass

instance1 和 instance2 共享 classVar,因为它们都是 TestClass 类型的对象。

print(instance1.classVar) # prints 0
TestClass.classVar = 1
print(instance1.classVar) # prints 1
print(instance2.classVar) # prints 1

但是,它们都有 instanceVar 的副本,因为它是与单个实例相关联的实例变量,而不是类。

print(instance1.instanceVar) # prints 0
print(TestClass.instanceVar) # error! instanceVar is not a class variable
instance1.instanceVar = 1
print(instance1.instanceVar) # prints 1
print(instance2.instanceVar) # prints 0

As Aaron said, if you try to access an instance variable, Python first checks the instance variables of that object, then the class variables of the object's type. Class variables function as default values for instance variables.

于 2009-08-20T14:25:21.473 回答