类变量和实例变量有什么区别?
- 2025-02-20 09:25:00
- admin 原创
- 27
问题描述:
Python 中的类变量和实例变量有什么区别?
class Complex:
a = 1
和
class Complex:
def __init__(self):
self.a = 1
使用调用:x = Complex().a
在两种情况下都将 x 分配给 1。
如能提供更深入的解答__init__()
,我们self
将不胜感激。
解决方案 1:
编写类块时,会创建类属性(或类变量)。您在类块中指定的所有名称(包括您定义的方法)都def
将成为类属性。
创建类实例后,任何引用该实例的对象都可以在其上创建实例属性。在方法内部,“当前”实例几乎总是与名称绑定self
,这就是您将这些视为“自变量”的原因。通常在面向对象的设计中,附加到类的代码应该可以控制该类实例的属性,因此几乎所有实例属性分配都是在方法内部完成的,使用self
方法参数中收到的对实例的引用。
类属性通常与Java、C# 或 C++ 等语言中的静态变量(或方法)进行比较。但是,如果您想更深入地理解,我会避免将类属性视为与静态变量“相同”。虽然它们通常用于相同的目的,但底层概念却截然不同。有关此内容的更多信息,请参阅下面的“高级”部分。
一个例子!
class SomeClass:
def __init__(self):
self.foo = 'I am an instance attribute called foo'
self.foo_list = []
bar = 'I am a class attribute called bar'
bar_list = []
执行此块后,有一个类SomeClass
,具有3个类属性:__init__
,,bar
和bar_list
。
然后我们将创建一个实例:
instance = SomeClass()
发生这种情况时,将执行SomeClass
的__init__
方法,并在其参数中接收新实例self
。此方法创建两个实例属性:foo
和foo_list
。然后将此实例分配给instance
变量,因此它与具有这两个实例属性的事物绑定:foo
和foo_list
。
但:
print instance.bar
给出:
I am a class attribute called bar
这是怎么发生的?当我们尝试通过点语法检索属性时,如果该属性不存在,Python 会执行一系列步骤来尝试满足您的请求。它接下来会尝试查看实例的类的类属性bar
。在本例中,它在 中找到了一个属性SomeClass
,因此返回了该属性。
顺便说一下,这也是方法调用的工作原理。mylist.append(5)
例如,当您调用 时,mylist
没有名为 的属性append
。但是的类mylist
有,并且它绑定到方法对象。该方法对象由位返回mylist.append
,然后(5)
位使用参数 调用该方法5
。
这样做的好处是,所有的实例都SomeClass
可以访问同一个bar
属性。我们可以创建一百万个实例,但我们只需要将一个字符串存储在内存中,因为它们都可以找到它。
但你得小心一点。看看下面的操作:
sc1 = SomeClass()
sc1.foo_list.append(1)
sc1.bar_list.append(2)
sc2 = SomeClass()
sc2.foo_list.append(10)
sc2.bar_list.append(20)
print sc1.foo_list
print sc1.bar_list
print sc2.foo_list
print sc2.bar_list
您认为这会打印出什么?
[1]
[2, 20]
[10]
[2, 20]
这是因为每个实例都有自己的 副本foo_list
,因此它们被分别附加到 。但所有实例共享对同一个 的访问权限bar_list
。因此当我们这样做时,sc1.bar_list.append(2)
它会影响sc2
,即使sc2
它还不存在!同样sc2.bar_list.append(20)
会影响bar_list
通过 检索的sc1
。这通常不是您想要的。
接下来是高级研究。:)
为了真正理解 Python,从 Java 和 C# 等传统静态类型 OO 语言开始,您必须学会重新思考一些类。
在 Java 中,类本身并不是一个真正的事物。当你编写一个类时,你更多的是在声明该类的所有实例都具有的一堆共同点。在运行时,只有实例(和静态方法/变量,但这些实际上只是与类关联的命名空间中的全局变量和函数,与 OO 无关)。类是你在源代码中写下实例在运行时的样子的方式;它们只“存在”在你的源代码中,而不是在正在运行的程序中。
在 Python 中,类并没有什么特别之处。它就像其他任何东西一样,是一个对象。因此,“类属性”实际上与“实例属性”完全相同;实际上只有“属性”。进行区分的唯一原因是我们倾向于以不同的方式使用属于类的对象和非属于类的对象。底层机制都是一样的。这就是为什么我说将类属性视为其他语言中的静态变量是错误的。
但 Python 类与 Java 风格的类的真正不同之处在于,就像任何其他对象一样,每个类都是某个类的实例!
在 Python 中,大多数类都是内置类的实例,称为type
。这个类控制类的常见行为,并使所有 OO 内容都按照它的方式进行。默认的 OO 方式是让类的实例具有自己的属性,并具有由其类定义的常见方法/属性,这只是 Python 中的一种协议。您可以根据需要更改它的大部分方面。如果您听说过使用元类,那么它就是定义一个类,该类是 之外的另一个类的实例type
。
关于类,唯一真正“特殊”的事情(除了所有使它们按照默认方式工作的内置机制之外)是类块语法,它使您可以更轻松地创建实例type
。这:
class Foo(BaseFoo):
def __init__(self, foo):
self.foo = foo
z = 28
大致相当于以下内容:
def __init__(self, foo):
self.foo = foo
classdict = {'__init__': __init__, 'z': 28 }
Foo = type('Foo', (BaseFoo,), classdict)
并且它将安排的所有内容classdict
成为所创建对象的属性。
因此,很容易看出,您可以通过Class.attribute
轻松访问类属性i = Class(); i.attribute
。i
和都是Class
对象,而对象具有属性。 这也使您很容易理解如何在创建类后对其进行修改;只需像分配其他对象一样分配其属性即可!
实际上,实例与用于创建它们的类没有特别特殊的关系。Python 通过隐藏__class__
属性来知道在哪个类中搜索实例中未找到的属性。您可以读取它以找出这是哪个类的实例,就像任何其他属性一样:c = some_instance.__class__
。现在您有一个c
绑定到类的变量,即使它可能与类的名称不同。您可以使用它来访问类属性,甚至可以调用它来创建更多实例(即使您不知道它是什么类!)。
您甚至可以分配给i.__class__
来更改它是哪个类的实例!如果您这样做,不会立即发生任何特别的事情。这并不是惊天动地的。它的全部含义是,当您查找实例中不存在的属性时,Python 将会查看 的新内容__class__
。由于这包括大多数方法,并且方法通常期望它们操作的实例处于某些状态,因此如果您随机执行此操作,通常会导致错误,并且这非常令人困惑,但这是可以做到的。如果您非常小心,您存储的东西__class__
甚至不必是一个类对象;Python 要做的就是在特定情况下查找属性,因此您所需要的只是一个具有正确类型属性的对象(除了一些警告,Python 确实会挑剔事物是类还是特定类的实例)。
现在可能就够了。希望(如果你已经读到这里)我没有让你感到太困惑。当你了解了 Python 的工作原理后,你会发现它很棒。:)
解决方案 2:
你所说的“实例”变量实际上并不是一个实例变量;它是一个类变量。请参阅有关类的语言参考。
在您的示例中,它a
似乎是一个实例变量,因为它是不可变的。当您分配一个可变对象时,可以看到它作为类变量的性质:
>>> class Complex:
>>> a = []
>>>
>>> b = Complex()
>>> c = Complex()
>>>
>>> # What do they look like?
>>> b.a
[]
>>> c.a
[]
>>>
>>> # Change b...
>>> b.a.append('Hello')
>>> b.a
['Hello']
>>> # What does c look like?
>>> c.a
['Hello']
如果使用self
,那么它将是一个真正的实例变量,因此每个实例都有自己独特的。创建新实例时,将调用a
对象的函数,并且是该实例的引用。__init__
`self`
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)