gpt4 book ai didi

python - 防止从子类访问实例变量,而不影响基类

转载 作者:太空狗 更新时间:2023-10-29 20:30:24 24 4
gpt4 key购买 nike

假设我有一个简单的类 Foo,它来自外部库,因此我不能直接更改它:

class Foo(object):
def __init__(self, x):
self.x = x

我想创建一个子类 Bar 并防止 xBar 的实例中更改,但仍然使用 xBar 的方法中。

这是我尝试过的,它可能会启发基本思想,但不幸的是它不起作用:

class Bar(Foo):

@property
def x(self):
return super().x

@x.setter
def x(self, value):
raise NotImplementedError('Do not change x directly, use "do_stuff()" instead')

def do_stuff(self, value):
if <something>:
super().x = value

基本上我已经围绕属性创建了一些包装函数 (do_stuff()),现在我想防止属性被直接更改,因为它可能会破坏包装函数。这可能以合理的方式实现吗?

编辑 以更好的例子说明我想要什么。我并不是要阻止他们看到变量 x,而是从 do_stuff()

外部更改它

最佳答案

如果您愿意完全避免继承,这应该更容易完成:

def main():
bar = Bar(123)
bar.fizz()
bar.buzz()
bar.fizz()
bar.set_x(456)
print('bar.x =', bar.x)
try:
bar.x = 123
except AttributeError:
print('bar.x cannot be set directly')
else:
raise AssertionError('an AttributeError should have been raised')
bar.mutate_x(789)
bar.fizz()
bar.set_x(0)
bar.fizz()
bar.mutate_x(1)
bar.fizz()
bar.set_x('Hello World')
bar.fizz()


class Foo:

def __init__(self, x):
self.x = x

def fizz(self):
print(self.x)

def buzz(self):
self.x = None


class Bar:

def __init__(self, x):
self.__foo = foo = Foo(x)
self.__copy_methods(foo)

def __copy_methods(self, obj):
for name in dir(obj):
if name.startswith('__') or name.endswith('__'):
continue
attr = getattr(obj, name)
if callable(attr):
setattr(self, name, attr)

@property
def x(self):
return self.__foo.x

def set_x(self, value):
if isinstance(value, int) and value > 0:
self.__foo.x = value

mutate_x = set_x

if __name__ == '__main__':
main()

关于python - 防止从子类访问实例变量,而不影响基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33368552/

24 4 0
文章推荐: c++ - 指针包装类 - 表现得像一个原始指针
文章推荐: c# - 提供对象类型时,如何告诉 JSON.NET 将 JArray 反序列化为 List