Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有Pass-through\uuuu set\uuuu命令的Python数据描述符_Python_Function_Methods_Set_Descriptor - Fatal编程技术网

带有Pass-through\uuuu set\uuuu命令的Python数据描述符

带有Pass-through\uuuu set\uuuu命令的Python数据描述符,python,function,methods,set,descriptor,Python,Function,Methods,Set,Descriptor,我在解决一个问题时遇到了点麻烦。我有一组专门的函数,它们将在整个程序中使用,基本上是动态可调用的,可以替换函数和方法。由于需要让它们正常工作以模拟方法的功能,这些函数重写\uuuuu get\uuuu,以提供允许访问检索对象的包装版本 不幸的是,如果直接在实例上设置该函数,\uuuuuu get\uuuuu将不起作用。这是因为当在实例的\uuuuu dict\uuuu中找到键时,只有“数据描述符”调用\uuuu get\uuuu函数。唯一的解决方案是:诱使python认为这是一个数据描述符。这涉

我在解决一个问题时遇到了点麻烦。我有一组专门的函数,它们将在整个程序中使用,基本上是动态可调用的,可以替换函数和方法。由于需要让它们正常工作以模拟方法的功能,这些函数重写
\uuuuu get\uuuu
,以提供允许访问检索对象的包装版本

不幸的是,如果直接在实例上设置该函数,
\uuuuuu get\uuuuu
将不起作用。这是因为当在实例的
\uuuuu dict\uuuu
中找到键时,只有“数据描述符”调用
\uuuu get\uuuu
函数。唯一的解决方案是:诱使python认为这是一个数据描述符。这涉及到在描述符上创建一个
\uuuuuuuuuuuuuuu
函数。理想情况下,我希望这个
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu设置
函数作为一个传递函数来工作(将控制返回给调用者,并继续进行评估,就好像它不存在一样)

有没有办法欺骗python,让它认为描述符是数据描述符,但让包含该描述符的类/实例仍然能够正常使用其setattr命令

另外,我知道可以通过调用方的
\uuuu getattribute\uuuu
覆盖来实现这一点。但是,这是一个糟糕的解决方案,因为我必须为内置的“对象”和任何覆盖它的东西执行此操作。这不是一个很好的解决方案

或者,如果有其他解决方案,我很乐意听到

下面是一个问题示例:
类描述符(对象):
定义获取(self、obj、objtype=None):
一无所获
类调用方(对象):
a=描述符()
打印
>>>没有
x=调用方()
打印
>>>没有
x、 a=描述符()
打印x.a
>>>   

最后一个案例应打印“无”以保持一致性

如果在描述符中添加
\uuuuu set\uuuu
,则会根据需要打印“无”。但是,这会使x.a=(某个值)的任何命令无法像以前那样工作。因为我不想弄乱这个功能,这是没有帮助的。任何解决方案都会很好

更正:我之前的想法仍然不起作用,因为我稍微误解了描述符处理。显然,如果一个描述符根本不在一个类上,它将永远不会被调用——不管集是什么。只有当存在同名的dict val和类访问器时,我的条件才有帮助。实际上,我正在寻找一个更符合以下思路的解决方案:但这并不包括让sun下的所有东西都继承一个专门的接口


不幸的是,鉴于对描述符接口的这种新理解,这可能是不可能的?为什么python会使decorator本质上是非动态的?

我认为最干净的解决方案是让
\uuuuuuuuu\uuuuuuuuuuuuuuu>单独运行,并在类上设置描述符——如果需要,包装原始类。即,代替
x.a=Descriptor()
,执行
setdesc(x,'a',Descriptor()
,其中:

class Wrapper(object): pass

def setdesc(x, name, desc):
  t = type(x)
  if not issubclass(t, wrapper):
    class awrap(Wrapper, t): pass
    x.__class__ = awrap
  setattr(x.__class__, name, desc)
当有人想要“在实例上设置”任何需要在类上设置才能工作的东西(特殊方法或描述符),但不想影响实例的原始类时,我建议使用这种方法


当然,只有当您有新样式的类时,这一切才能很好地工作,但是说明符无论如何都不能很好地处理旧样式的类;-)。

我认为最干净的解决方案是将
\uuuu set\uuuuuu>单独放置,并在类上设置说明符——如果需要,包装原始类。即,代替
x.a=Descriptor()
,执行
setdesc(x,'a',Descriptor()
,其中:

class Wrapper(object): pass

def setdesc(x, name, desc):
  t = type(x)
  if not issubclass(t, wrapper):
    class awrap(Wrapper, t): pass
    x.__class__ = awrap
  setattr(x.__class__, name, desc)
当有人想要“在实例上设置”任何需要在类上设置才能工作的东西(特殊方法或描述符),但不想影响实例的原始类时,我建议使用这种方法


当然,只有当你有新风格的类时,它才能很好地工作,但是说明符无论如何都不能很好地处理旧风格的类;-)。

我想我的问题可能有一个答案,尽管它不是那么漂亮-它确实回避了这个问题。我目前的攻击计划是做python做的事情——手动绑定函数。我已经在使用未绑定函数的get命令生成绑定类型函数。一种可能的解决方案是强制任何想要设置新函数的人手动绑定它。这很烦人,但并不疯狂。Python实际上让您这样做(如果您只是将一个函数作为属性设置到一个实例上,它不会被绑定)


让这种情况自动发生仍然很好,但强制正在设置新函数的人使用x.a=Descriptor()。get(x)在这种情况下,它将给出所需的行为(例如,对于这一点,也是如此)。这不是一个通用的解决方案,但它可以解决这个有限的问题,方法绑定基本上是模拟的。话虽如此,如果有人有更好的解决方案,我还是很高兴听到。我想我的问题可能只有一个答案,尽管它并不那么漂亮——它确实回避了这个问题。我目前的攻击计划是做python做的事情——手动绑定函数。我已经在使用未绑定函数的get命令生成绑定类型函数。一种可能的解决方案是强制任何想要设置新函数的人手动绑定它。这很烦人,但并不疯狂。Python实际上让您这样做(如果您只是将一个函数作为属性设置到一个实例上,它不会被绑定)

让这种情况自动发生仍然很好,但强制正在设置新函数的人使用x.a=Descriptor()。get(x)在本例中,这将给出