所以,我创建了一些课程
class Some:
@classmethod
def __init__(cls, somevar):
cls.somevar = somevar
@classmethod
def read(cls):
return cls.somevar
现在我试图在外部设置变量并从类中读取它:
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
>>>> [1, 2, 3]
但是在类外部调用相同的命名变量却给了我预期的输出,
print(instance.somevar)
>>>> [4, 5, 6]
我对OOP的误解是什么?
编辑
我的目标是创建Some
的多个实例,这些实例将具有自己的值。
答案 0 :(得分:5)
实际上,您误解了 class变量是什么。当您使用
instance.somevar = [4, 5, 6]
它不会改变您认为的价值。相反,您需要做的是像这样更改实际的类变量,
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
instance2 = Some([4, 5, 6])
print(instance.read())
>>>>
[1, 2, 3]
[4, 5, 6]
的确,不要忘记使用@classmethod
装饰器,cls
实际上是类本身。因此,在您的情况下,cls.somevar
将在所有类之间共享。另外,由于装饰了__init__
,因此每次实例化该类时都将更改该变量的值,如上面的示例中的经验所示。
请注意,这可能不是您要查找的实现。您可能想像这样使用self
class Some:
def __init__(self, somevar):
self.somevar = somevar
def read(self):
return self.somevar
instance = Some([1, 2, 3])
print(instance.read())
instance.somevar = [4, 5, 6]
print(instance.read())
>>>>
[1, 2, 3]
[4, 5, 6]
答案 1 :(得分:1)
使用print(instance.somevar)
来获取somevar值,但是您可以在函数内部而不是全局范围内对其进行更改
答案 2 :(得分:1)
您可能需要更好地理解类和实例之间的区别。也许以下代码会有所帮助。
class Some():
classvar = 123
def __init__ (self, value):
self.instvar = value
def read_instvar (self):
return self.instvar
def read_classvar (self):
return self.__class__.classvar
@classmethod
def update_classvar(cls, value):
cls.classvar = value
所以现在我们可以创建几个对象,并查看它们如何相互作用。
>>> first = Some(12)
>>> second = Some(34)
>>> second.update_classvar(456)
>>> first.read_classvar()
456
>>> first.read_instvar()
12
>>> second.read_instvar()
34
>>> second.read_classvar()
456
观察instvar
是每个实例的属性;因此first
的值不同于second
的值。但是请注意,classvar
在这些实例之间是如何共享的,因为它们属于同一类,并且class变量是该类的属性,而不是任何一个实例的属性。具体而言,即使我们通过second
更改了class变量,该更改在first
中也可见。
答案 3 :(得分:0)
它更像是示波器问题。
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
>> [1, 2, 3]
Some.somevar = [4, 5, 6]
print(instance.read())
>> [4, 5, 6]
全部基于以下事实:在Python中,可以在实例范围和类范围中使用两个具有相同名称的变量,并且它们具有不同的值。