类变量在Python中的对象中常见吗

问题描述 投票:0回答:1

假设我想使用类变量来实现对象之间的公共变量(类似于java/c++中的static)。

当我使用对象访问类变量时,它显示默认值。 然后我通过对象更新了类变量,它没有更新其他对象的类变量。 当通过其他对象或类名直接访问类变量时,它显示旧值。

为什么会这样,Python中如何制作类/静态变量(对象之间通用)

# Class for Computer Science Student
class CSStudent:
    
    stream = 'cse'               # Class Variable
    def __init__(self,name):
        self.name = name     # Instance Variable

# Objects of CSStudent class
a = CSStudent('Geek')
b = CSStudent('Nerd')


print(a.stream) # prints "cse"
print(b.stream) # prints "cse"
print(a.name) # prints "Geek"
print(b.name) # prints "Nerd"

# Class variables can be accessed using class
# name also
print(CSStudent.stream) # prints "cse"

# Now if we change the stream for just a it won't be changed for b
a.stream = 'ece'
b.stream = 'abc'
print(CSStudent.stream)  # prints 'ece'
print(a.stream) # prints 'ece'
print(b.stream) # prints 'abc'
python class static-variables
1个回答
3
投票

您需要了解查找程序。

首先,实例和类都有自己的名称空间。只有类变量在所有实例之间共享。类和实例的命名空间可通过

__dict__
属性访问。

当您从实例访问属性时,Python 首先查看实例的名称空间,如果可以找到它,则返回它,否则它将在其类中找到它!

class CSStudent:
    stream = "cse"

a = CSStudent()
b = CSStudent()
print("stream" in a.__dict__)          # False
print("stream" in b.__dict__)          # False
print("stream" in CSStudent.__dict__)  # True

print(a.stream)  # cse
print(b.stream)  # cse

所以

a
b
没有那个
stream
,只有班级有。

现在

a.stream = "something"
会将该属性添加到该特定实例的命名空间中。

a.stream = "something"
print("stream" in a.__dict__)          # True
print("stream" in b.__dict__)          # false
print("stream" in CSStudent.__dict__)  # True

现在,如果您访问

a.stream
,它会在
a
的命名空间中找到它并返回它,但因为
b
没有该名称空间,所以它将在类中找到它。(共享的)

print(a.stream)  # something
print(b.stream)  # cse

如果您希望更改反映所有实例,则需要在所有实例之间共享它的类上进行更改。

class CSStudent:
    stream = "cse"

a = CSStudent()
b = CSStudent()
print(a.stream)     # cse
print(b.stream)     # cse
CSStudent.stream = "something"
print(a.stream)     # something
print(b.stream)     # something

始终思考谁拥有什么。然后考虑优先级,首先检查实例命名空间。

注意:我简化了解释,没有提及什么是描述符,因为我们这里没有。稍后再看一下。您会惊讶地发现实际上总是首先检查类名称空间!

© www.soinside.com 2019 - 2024. All rights reserved.