我在解决我正在研究的问题时遇到了一些问题。我有一组专门的函数,它们将在整个程序中使用,它们基本上是可以替换函数和方法的动态可调用函数。由于需要让它们正常工作以模拟方法的功能,这些函数重写__get__
以提供一个包装版本,以提供对检索对象的访问权限。
不幸的是,__get__
如果函数直接在实例上设置,则不起作用。这是因为在实例中找到键时,只有“数据描述符”才会调用该__get__
函数。__dict__
想到的唯一解决方案是:欺骗 python 认为这是一个数据描述符。这涉及在描述符上创建一个__set__
函数。理想情况下,我希望这个__set__
函数作为传递(将控制权返回给调用者并继续评估,就好像它不存在一样)。
有什么方法可以欺骗 python 认为描述符是数据描述符,但让包含的类/实例仍然能够正常使用它的 setattr 命令?
另外,我知道可以通过覆盖__getattribute__
调用者来做到这一点。但是,这是一个糟糕的解决方案,因为我必须对内置的“对象”和任何覆盖它的东西执行此操作。不完全是一个很好的解决方案。
或者,如果有任何替代解决方案,我很乐意听到。
这是一个问题示例:
class Descriptor(object):
def __get__(self, obj, objtype = None):
return None
class Caller(object):
a = Descriptor()
print a
>>> None
x = Caller()
print a
>>> None
x.a = Descriptor()
print x.a
>>> <__main__.Descriptor object at 0x011D7F10>
最后一种情况应打印“无”以保持一致性。
如果您将 a 添加__set__
到描述符,这将打印“无”(根据需要)。但是,这会使 xa = (some value) 的任何命令无法像以前一样工作。由于我不想弄乱此功能,因此没有帮助。任何解决方案都会很棒。
更正:我之前的想法仍然行不通,因为我稍微误解了描述符处理。显然,如果一个描述符根本不在一个类上,它将永远不会被调用——不管set。我的条件只有在有一个 dict val 和一个同名的类访问器时才有帮助。我实际上正在寻找一个更类似于以下内容的解决方案:http: //blog.brianbeck.com/post/74086029/instance-descriptors但这并不涉及让阳光下的一切都继承一个专门的接口。
不幸的是,鉴于对描述符接口的这种新理解,这可能是不可能的?为什么哦,为什么 python 会使装饰器本质上是非动态的?