这里没有直接的解决方案可能有点棘手,但我也对更复杂的解决方案感到满意:
我有一个绑定到全局实例的实例绑定数据描述符],但我希望将其作为函数参数传递而无需进行评估(即执行__get__()
)。在此代码示例中,它不起作用,并且描述符将类型为10
的当前值int
传递给函数参数,而不是自身:
"""A 'instance binding data descriptor' that sets and returns values normally and prints a message logging their access. The `x`-value is stored in the instance dictionary `my_instance.__dict__`. """ def __init__(self, init_value=None): self.init_value = init_value def __get__(self, instance, owner): value = getattr(instance, self.__name__ + '_value') print('I AM A DATA-DESCRIPTOR retrieving `{}` value: {}'.format(self.__name__, value)) return value def __set__(self, instance, value): print('I AM A DESCRIPTOR updating `{}` to value: {}'.format(self.__name__, value)) setattr(instance, self.__name__ + '_value', value) class MyClass(object): x = RevealAccess(init_value=10) def __new__(cls): instance = object.__new__(cls) for desc_name in [key for key in cls.__dict__.keys() if isinstance(cls.__dict__[key], RevealAccess)]: cls.__dict__[desc_name].__name__ = desc_name instance.__dict__[desc_name + '_value'] = cls.__dict__[desc_name].init_value return instance my_instance = MyClass() def func_with_descriptor_as_argument(descriptor_arg): print('\n\nINSIDE the function `descriptor_arg=my_instance.x`results in: {}'.format(descriptor_arg)) print('`type(descriptor_arg)`: {}'.format(type(descriptor_arg))) print('Changing `my_instance.x` value results in:') descriptor_arg = 5 print('INSIDE the function after changing `my_instance.x` = {}\n\n'.format(descriptor_arg)) if __name__ == '__main__': print('\n\nOUTSIDE the function `my_instance.x`: {}'.format(my_instance.x)) print('Changing `my_instance.x` value results in:') my_instance.x = 5 print('OUTSIDE the function after changing `my_instance.x` = {}\n\n'.format(my_instance.x)) print('Reset:') my_instance.x = 10 func_with_descriptor_as_argument(descriptor_arg=my_instance.x)
输出为:
I AM A DATA-DESCRIPTOR retrieving `x` value: 10 OUTSIDE the function `my_instance.x`: 10 Changing `my_instance.x` value results in: I AM A DESCRIPTOR updating `x` to value: 5 I AM A DATA-DESCRIPTOR retrieving `x` value: 5 OUTSIDE the function after changing `my_instance.x` = 5 Reset: I AM A DESCRIPTOR updating `x` to value: 10 I AM A DATA-DESCRIPTOR retrieving `x` value: 10 INSIDE the function `descriptor_arg=my_instance.x`results in: 10 `type(descriptor_arg)`: <class 'int'> Changing `my_instance.x` value results in: INSIDE the function after changing `my_instance.x` = 5
我的确知道这种方式不起作用。但是我想要的是在函数内部操作全局实例字典值
my_instance.__dict__['x_value']
。我必须在许多实例和函数中重复此操作,并且实际的描述符也在做其他事情(在此示例中,它仅打印“ I AM ...”,但在我的情况下,例如,类型检查,触发其他进程等),因此直接字典操作是不希望的。它必须由描述符完成。
我可以构建某种类型的描述符,该描述符可以将对函数参数的引用传递为等效的吗?
我一直在寻找不同的选择:
my_instance
和字符串名称x
或作为元组,并在函数内部使用getattr()
,setattr()
。我不喜欢它,因为它用于框架,对任何人都不适合。inspect
,一些AST
包,然后在重载的__get__()
内部建立适当的引用并返回它。我可以管理检测部分,但不知道参考的外观如何?将其包装在另一个描述符中吗?最后,函数自变量应该像直接可调用的描述符一样在函数内起作用,但要获取/设置全局字典my_instance.__dict__['x_value']
(并执行所提及的所有其他操作)。
我对任何想法都很高兴,并期待讨论!
这在没有直接解决方案的情况下可能会有些棘手,但我也对更复杂的解决方案感到满意:我有一个实例绑定数据描述符,该描述符绑定到一个我...
我找到了一个很好的解决方案,它是一种类包装器,如果尝试从中获取不存在的属性,则描述符所有者实例my_instance
创建并在__getattr__()
中返回。