我如何将实例绑定描述符作为函数的引用参数?

问题描述 投票:0回答:1

这里没有直接的解决方案可能有点棘手,但我也对更复杂的解决方案感到满意:

我有一个绑定到全局实例的实例绑定数据描述符],但我希望将其作为函数参数传递而无需进行评估(即执行__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'](并执行所提及的所有其他操作)。

我对任何想法都很高兴,并期待讨论!

提前THX !!

这在没有直接解决方案的情况下可能会有些棘手,但我也对更复杂的解决方案感到满意:我有一个实例绑定数据描述符,该描述符绑定到一个我...

python function methods parameter-passing typedescriptor
1个回答
0
投票

我找到了一个很好的解决方案,它是一种类包装器,如果尝试从中获取不存在的属性,则描述符所有者实例my_instance创建并在__getattr__()中返回。

© www.soinside.com 2019 - 2024. All rights reserved.