gpt4 book ai didi

python - 绑定(bind)需要访问私有(private)变量的外部方法: Feature or Bug?

转载 作者:行者123 更新时间:2023-12-01 06:00:00 25 4
gpt4 key购买 nike

简短版本:绑定(bind)到实例的外部方法无法通过 self.__privatevarname 直接访问私有(private)变量。这是一个功能还是一个错误?

扩展版本(带有解释和示例):

Python: Bind an Unbound Method? ,Alex Martelli 解释了一种将函数绑定(bind)到实例的简单方法。

使用此方法,可以使用外部函数在类中设置实例方法(在 __init__ 中)。

但是,当绑定(bind)到实例的函数需要访问私有(private)变量时,这种情况就会失效。这是因为名称修改发生在 compile 期间。步骤 _Py_Mangle,因此该函数永远没有机会调用 __getattribute__('_classname__privatevarname')

例如,如果我们定义一个简单的外部加法函数来访问私有(private)实例变量__obj_val:

def add_extern(self, value):
return self.__obj_val + value

并将其绑定(bind)到__init__中的每个实例,同时还在类定义中定义类似的实例方法add_intern

class TestClass(object):
def __init__(self, object_value):
self.__obj_val = object_value
self.add_extern = add_extern.__get__(self, TestClass)

def add_intern(self, value):
return self.__obj_val + value

那么内部方法将起作用,但外部绑定(bind)方法将引发异常:

>>> t = TestClass(0)
>>> t.add_intern(1)
1
>>> t.add_extern(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in add_extern
AttributeError: 'TestClass' object has no attribute '__obj_val'

POSTSCRIPT:您可以通过覆盖 __getattribute__ 来为您进行损坏来克服此缺点:

class TestClass(object):
...
def __getattribute__(self, name):
try:
return super(TestClass, self).__getattribute__(name)
except AttributeError:
# mimic behavior of _Py_Mangle
if not name.startswith('__'): # only private attrs
raise
if name.endswith('__'): # don't mangle dunder attrs
raise
if '.' in name: # don't mangle for modules
raise
if not name.lstrip('_'): # don't mangle if just underscores
raise

mangled_name = '_{cls_name}{attr_name}'.format(
cls_name=self.__class__.__name__, attr_name=name)
return super(TestClass, self).__getattribute__(mangled_name)

但是,这不会将变量保留给外部调用者,这是我们不希望的。

最佳答案

由于Python的name-mangling ,存储在 t 上的属性的实际名称是 _TestClass__obj_val (正如您在 dir(t) 中看到的那样)。外部函数尚未在类上定义,只是寻找 __obj_val .

损坏的名称存储在函数的代码对象中(例如 t.add_extern.func_code.co_names )并且是只读的,因此没有简单的方法来更新它。

所以有理由不使用该技术......至少对于损坏的名称。

关于python - 绑定(bind)需要访问私有(private)变量的外部方法: Feature or Bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10907103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com