Reb*_*ebs 4 python methods descriptor python-2.7
我有数据描述符适用于具有__set__和的对象__get__.
但是,似乎类描述符不支持__set__.这样做会使用指定的值替换描述符对象本身.
以下代码演示了这一点
from __future__ import print_function
class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')
class Class(object):
descriptor = Descriptor()
print('Object')
a = Class()
a.descriptor
a.descriptor = 1
print('Class')
Class.descriptor
Class.descriptor = 2
Run Code Online (Sandbox Code Playgroud)
哪个输出
Object
__get__
__set__
Class
__get__
Run Code Online (Sandbox Code Playgroud)
如您所见,类级别__set__没有被调用.
是否有一些解决方法或黑客(无论多么可怕)允许__set__类上的数据描述符?
为了清楚起见,我不希望调用代码来实现任何"黑客".我希望调用代码按照预期的方式工作,但任何黑客都是"幕后".
使用Python 2.7
我不会涉及整个描述符协议.我自己并不完全理解 ; 事实上,你已经提醒我,我需要放弃懒惰,真正潜入它.同时,我会这样说:
我所理解的是描述符只会在实例上发挥作用.现在,你可能已经知道了这一点,这就是为什么你想知道是否有一个黑客来克服这个限制.
如果你对元类有一点熟悉,你就会知道类也是实例.类可以是类的实例,也可以是实例等等.这很棒,因为你问的内容会是这样的:
class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')
class MetaClass(type):
descriptor = Descriptor()
class Class(object):
__metaclass__ = MetaClass
# This will work fine when you do Class.descriptor, as you asked
# but it will raise an AttributeError if you do
# a = Class()
# a.descriptor
# Read on for the full explanation...
Run Code Online (Sandbox Code Playgroud)
descriptor定义的变量MetaClass仅对Class类可见.Class尝试调用它的任何实例都会给你一个AttributeError.这是因为类的实例在搜索属性时会__dict__在搜索类之前搜索它们__dict__,但它不会搜索类的类__metaclass__.现在,如果你想同时使用它并为类及其实例使用相同的变量名(虽然我不推荐它,因为它会引起混淆),你可以这样做:
class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')
class MetaClass(type):
descriptor = Descriptor()
class Class(object):
__metaclass__ = MetaClass
descriptor = Descriptor()
Run Code Online (Sandbox Code Playgroud)
此时你可能想知道:如果一个实例__dict__在搜索它的类之前搜索它自己,那么调用' Class.descriptor'将不会选择' a.descriptor'使用的相同描述符(正如你所观察到的那样,它将不起作用)如果Class.descriptor它本质上是它自己的实例变量(来自元类POV)?
答案是数据描述符(具有__get__和__set__定义的描述符)与非数据描述符(仅定义的__get__)相比,优先于实例变量.换句话说,该descriptor变量MetaClass是一个Class将回升,因为它的优先级高于Class自己的descriptor变量.这同样适用于所述Class的实例,它可以自动拾取descriptor中定义的变量Class.
我希望我没有让你困惑.这个东西很容易忘记,我认为是双倍的,因为在大多数情况下理解这种魔法并不是很常见也不必要.我必须在这一个上恢复我的记忆!好问题 :)
| 归档时间: |
|
| 查看次数: |
486 次 |
| 最近记录: |