gpt4 book ai didi

python - 类变量,instance.var 和 instance.__class__.var 的区别

转载 作者:太空宇宙 更新时间:2023-11-04 09:44:34 25 4
gpt4 key购买 nike

我看到这被标记为“类变量和实例变量之间有什么区别?”的副本但是我不相信我在我的示例中使用了任何实例变量,我的类都没有 __init__ 我正在以两种不同的方式编辑类变量并试图理解它们之间的区别, 不是类和实例变量之间的区别。

我试图了解仅使用 .var 和使用 .__class__.var 调用类变量之间的区别。我认为这与子类化有关,所以我编写了以下代码。

class Foo:
foo = 0

class Bar(Foo):
bar = 1

def print_class_vals(f, b):
""" prints both instant.var and instant.__class__.var for foo and bar"""
print("f.foo: {}, {} "
"b.foo: {}, {} "
"b.bar: {}, {} "
"".format(f.foo, f.__class__.foo,
b.foo, b.__class__.foo,
b.bar, b.__class__.bar))

f = Foo()
b = Bar()
print_class_vals(f, b)

Foo.foo += 1
print_class_vals(f, b)

Bar.foo += 1
print_class_vals(f, b)

Bar.bar += 1
print_class_vals(f, b)

输出如下:

f.foo: 0, 0, b.foo: 0, 0, b.bar: 1, 1 
f.foo: 1, 1, b.foo: 1, 1, b.bar: 1, 1
f.foo: 1, 1, b.foo: 2, 2, b.bar: 1, 1
f.foo: 1, 1, b.foo: 2, 2, b.bar: 2, 2

我似乎找不到调用 inst.varinst.__class__.var 之间的任何区别。它们有何不同,我应该在什么时候使用一个而不是另一个?

最佳答案

同时 Gabriel Reis's answer完美地解释了这种特殊情况,f.foof.__class__.foo 实际上 有区别 即使 foo 未被实例属性隐藏

比较:

>>> class Foo:
... foo = 1
... def bar(self): pass
... baz = lambda self: None
>>> f = Foo()
>>> f.foo
1
>>> f.__class__.foo
1
>>> f.bar
<bound method Foo.bar of <__main__.Foo object at 0x11948cb00>>
>>> f.__class__.bar
<function __main__.Foo.bar(self)>
>>> f.bar()
>>> f.__class__.bar()
TypeError: bar() missing 1 required positional argument: 'self'

f.baz也是如此。

不同之处在于,通过直接访问 f.__class__.foo,您将绕过 descriptor protocol ,这是使方法、@property 和类似的东西起作用的东西。

如果你想要完整的细节,请阅读链接的 HOWTO,但简短的版本是它比 Gabriel 的回答说的要多一些:

Python will look up for a name (attribute) first in the instance namespace/dict. If it doesn't find there, then it will look up in the class namespace. If it still doesn't find there, then it will walk through the base classes respecting the MRO (method resolution order).

但是如果它在类命名空间(或任何基类)中找到它,并且它找到的是一个描述符(一个具有 __get__ 方法的值),它会执行一个额外的步骤。细节取决于它是数据描述符还是非数据描述符(基本上,它是否有一个__set__方法),但简短的版本是,而不是给你值,它会对该值调用 __get__ 并为您提供该值返回的内容。函数有一个返回绑定(bind)方法的__get__方法;属性有一个调用属性get方法的__get__方法;等

关于python - 类变量,instance.var 和 instance.__class__.var 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50311057/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com