Mar*_*nen 9 python inheritance class python-3.x
假设我有一个简单的类Foo,它来自外部库,因此我无法直接更改它:
class Foo(object):
def __init__(self, x):
self.x = x
Run Code Online (Sandbox Code Playgroud)
我想创建一个子类Bar并防止x从实例中更改Bar,但仍然使用xin Bar的方法.
这是我尝试过的,它可能会启发基本的想法,但不幸的是它不起作用:
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
Run Code Online (Sandbox Code Playgroud)
所以基本上我已经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()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
791 次 |
| 最近记录: |