为什么托管属性只适用于类属性而不适用于 python 中的实例属性?

发布于 2024-07-11 17:10:34 字数 1009 浏览 12 评论 0原文

为了说明这个问题,请检查以下代码:

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return self._v
  def __set__(self, obj, value):
    self._v = value
    print "set", self, obj, value
    return None

class SomeClass1(object):
  m = MyDescriptor()

class SomeClass2(object):
  def __init__(self):
    self.m = MyDescriptor()

x1 = SomeClass1()
x2 = SomeClass2()

x1.m = 1000
# ->  set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000
x2.m = 1000 # I guess that this overwrites the function. But why?
# ->
print x1.m
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000
print x2.m
# -> 10000
  1. 为什么 x2.m = 1000 不调用 __set__ 函数? 看来这会覆盖该功能。 但为什么?
  2. x1 中的 _v 在哪里? 它不在 x1._v

To illustrate the question check the following code:

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return self._v
  def __set__(self, obj, value):
    self._v = value
    print "set", self, obj, value
    return None

class SomeClass1(object):
  m = MyDescriptor()

class SomeClass2(object):
  def __init__(self):
    self.m = MyDescriptor()

x1 = SomeClass1()
x2 = SomeClass2()

x1.m = 1000
# ->  set <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> 10000
x2.m = 1000 # I guess that this overwrites the function. But why?
# ->
print x1.m
# -> get <__main__.MyDescriptor object at 0xb787c7ec> <__main__.SomeClass1 object at 0xb787cc8c> <class '__main__.SomeClass1'> 10000
print x2.m
# -> 10000
  1. Why doesn't x2.m = 1000 not call the __set__-function? It seems that this overwrites the function. But why?
  2. Where is _v in x1? It is not in x1._v

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

許願樹丅啲祈禱 2024-07-18 17:10:34

回答你的第二个问题,_v在哪里?

您的描述符版本将 _v 保留在描述符本身中。 描述符的每个实例(类级实例 SomeClass1 和类 SomeClass2 的对象中的所有对象级实例都将具有不同的值 _v< /code>。

此版本更新了与描述符关联的对象,这意味着对象(SomeClass1x2)将包含属性 _v。

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return obj._v
  def __set__(self, obj, value):
    obj._v = value
    print "set", self, obj, value

To answer your second question, where is _v?

Your version of the descriptor keeps _v in the descriptor itself. Each instance of the descriptor (the class-level instance SomeClass1, and all of the object-level instances in objects of class SomeClass2 will have distinct values of _v.

Look at this version. This version updates the object associated with the descriptor. This means the object (SomeClass1 or x2) will contain the attribute _v.

class MyDescriptor(object):
  def __get__(self, obj, type=None):
    print "get", self, obj, type
    return obj._v
  def __set__(self, obj, value):
    obj._v = value
    print "set", self, obj, value
日裸衫吸 2024-07-18 17:10:34

您应该阅读

它会覆盖该函数,因为您没有重载 SomeClass 的 __set____get__ 函数,而是重载 MyDescriptor 类的函数。 也许您希望 SomeClass 继承 MyDescriptor? SomeClass1 打印“get”和“set”输出,因为它是静态方法 AFAIK。 有关详细信息,请阅读上面的链接。

You should read this and this.

It overwrites the function because you didn't overload the __set__ and __get__ functions of SomeClass but of MyDescriptor class. Maybe you wanted for SomeClass to inherit MyDescriptor? SomeClass1 prints the "get" and "set" output because it's a static method AFAIK. For details read the upper links.

傲影 2024-07-18 17:10:34

我找到了x1_v:它位于SomeClass1.__dict__['m']._v

中 对于S.Lott建议的版本其他答案:_vx1._v

I found _v of x1: It is in SomeClass1.__dict__['m']._v

For the version suggested by S.Lott within the other answer: _v is in x1._v

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文