gpt4 book ai didi

python - 在注入(inject)方法中访问私有(private)变量 - python

转载 作者:太空狗 更新时间:2023-10-30 00:09:33 25 4
gpt4 key购买 nike

问题在最后

我想做的是:

  1. 将属性注入(inject)创建的对象并设置它而不是变量(成功)
  2. 向创建的对象注入(inject)方法(我们称它为METHOD),对象之前没有这样的方法(成功)
  3. 使用 self 从属性调用 public 另一个方法(成功)
  4. 使用 self 从属性调用方法(成功)
  5. 使用 self 从 METHOD 获取私有(private)类变量(失败)

现在,这是一些代码:

from types import MethodType
def add_property(instance, name, method):
cls = type(instance)
cls = type(cls.__name__, (cls,), {})
cls.__perinstance = True
instance.__class__ = cls
setattr(cls, name, property(method))

def add_variable(instance, name, init_value = 0 ):
setattr(type(instance), name, init_value)

class Simulation:
def __init__(self):
self.finished = False
self.__hidden = -10

def someloop(self):
while not self.finished:
self.__private_method()

def __private_method(self):
pass

def public_method(self):
pass

def mocked_method(self):
print(type(self))
print(self.__dict__)
print(self.__hidden)

def finished(self):

print("Execute finished",type(self))
self.public_method()
self.mocked_update()
return True


simulation = Simulation()
add_property(simulation, "finished", finished)
add_variable(simulation, "count_finished", 0)
simulation.mocked_update = MethodType(mocked_method, simulation)
simulation.someloop()

产生了什么代码(那些打印):

Execute finished '<class '__main__.Simulation'>
<class '__main__.Simulation'>
{'finished': False, '_Simulation__hidden': -10, 'mocked_update': <bound method mocked_method of <__main__.Simulation object at 0x030D2F10>>}
(...)
AttributeError: 'Simulation' object has no attribute '__hidden'

如您所见,self 是它应该的样子(模拟类),它已正确注入(inject),但它不起作用。如果您想知道:

print(self._Simulation__hidden)

显然在 mocked_update 中工作。

因此我的问题是:我有机会使用 self 访问这个变量吗?

动机

既然评论区有问题:

这没有任何实际用途,只是一个实验。

最佳答案

“私有(private)”成员的名称修饰严格在类定义内完成。要实现预期目的,即将 self.__hidden 转换为 self._Simulation_hidden,您只需在适当命名的类中定义它

例如:

def make_mocked_method():
class Simulation:
# this is your code, but now its inside a class stanza so '__' will be mangled
def mocked_method(self):
print(type(self))
print(self.__dict__)
print(self.__hidden)

return Simulation.mocked_method

现在 mocked_method 将正确访问所需的属性:

simulation.mocked_update = MethodType(make_mocked_method(), simulation)
simulation.someloop()

给出:

<class '__main__.Simulation'>
{'finished': False, 'mocked_update': <bound method make_mocked_method.<locals>.Simulation.mocked_method of <__main__.Simulation object at 0x101c00a58>>, '_Simulation__hidden': -10}
-10

扩展

这依赖于我们对要添加方法的类的名称进行硬编码 (Simulation)。为避免这种情况,我们可以改用 exec:

def make_mocked_method(cls):
txt = """class {}:
def mocked_method(self):
print(type(self))
print(self.__dict__)
print(self.__hidden)
""".format(cls.__name__)
ns = {}
exec(txt, ns)
return ns[cls.__name__].mocked_method

不幸的是,我们希望添加的函数必须定义为文本,它不能是一些已经定义的任意函数对象。 (这可能可以通过使用 inspect 找到它的源代码然后使用 exec 在类节中重新编译该源代码来解决(并明智地选择 globals).

关于python - 在注入(inject)方法中访问私有(private)变量 - python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41884899/

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