有什么办法可以阻止子类覆盖基类中的方法吗?
我的猜测是没有,但我来自.NET世界,我正在努力使我的API尽可能健壮,所以任何输入都非常感激.
class Parent:
def do_something(self):
'''This is where some seriously important stuff goes on'''
pass
class Child(Parent):
def do_something(self):
'''This should not be allowed.'''
pass
Run Code Online (Sandbox Code Playgroud)
是否有可能强制执行此操作?我知道编译器不会有帮助,所以可能通过一些运行时检查?或者它不是一种传播事物的pythonic方式?
我正在使用相当大的OOP代码库,我想注入一些跟踪/日志记录。最简单的方法是在一些基类的某些方法周围引入一个装饰器,但是不幸的是装饰器没有被继承。
我确实尝试过以下操作:
def trace(fn):
def wrapper(instance, *args, **kwargs):
result = fn(instance, *args, **kwargs)
# trace logic...
return result
return wrapper
class BaseClass(object):
def __init__(self, ...):
...
self.__call__ = trace(self.__call__) # line added to end of method
Run Code Online (Sandbox Code Playgroud)
...并且当__call__方法被包裹(我可以从印刷实例信息发送到控制台看到)的wrapper预期不执行功能。
我还简要地研究了基于此答案的元类,但是它立即破坏了使用自省的系统其他部分,因此我认为这是不可行的。
还有其他方法可以强制这些装饰器围绕__call__从其继承的类的方法应用BaseClass吗?
我有一种情况,我想强制从某个(抽象)类继承的每个类来实现一个方法。这是我通常会使用@abstractmethod 实现的目标。但是,考虑到这种多重继承的情况:
from abc import ABCMeta, abstractmethod
class A(object):
__metaclass__ = ABCMeta
@abstractmethod
def very_specific_method(self):
pass
class B(A):
def very_specific_method(self):
print 'doing something in B'
class C(B):
pass
Run Code Online (Sandbox Code Playgroud)
我也想强制C实施该方法。我希望每个直接或间接继承 A 的类都被强制实现该方法。这可能吗?
澄清:我希望这适用于特定方法,而不是所有抽象方法。抽象方法应该继续以相同的方式工作,但也许应该创建一个新的装饰器来指示不同类型的方法。
旁注:我在问题中使用了 abc,因为这似乎与该问题最相关。我了解抽象方法通常如何工作并定期使用它们。这是一种不同的情况,我不介意不是通过 abc 完成的。
我想创建一个定义特定接口的类,然后要求所有子类都符合该接口。例如我想定义一个类
class Interface:
def __init__(self, arg1):
pass
def foo(self, bar):
pass
Run Code Online (Sandbox Code Playgroud)
然后请放心,如果我持有任何a具有 type A( 的子类)的元素Interface,那么我可以称a.foo(2)它会起作用。
看起来这个问题几乎解决了问题,但在这种情况下,由子类来显式更改它的元类。
理想情况下,我正在寻找类似于 Rust 中的 Traits 和 Impls 的东西,我可以在其中指定特定的 Trait 以及该 Trait 需要定义的方法列表,然后我可以确信具有该 Trait 的任何对象都具有这些方法定义的。
有没有办法在Python中做到这一点?
我有一个具有retrieve() 方法的超类,它的每个子类都实现了自己的retrieve() 方法。我希望每个retrieve() 方法都被装饰以在它接收到相同的参数时缓存返回值,而不必在每个子类中装饰该方法。
装饰器似乎没有被继承。我可能会调用超类的方法,该方法将依次设置缓存,但目前我的超类引发了一个 NotImplemented 异常,我喜欢。
import json
import operator
from cachetools import cachedmethod, TTLCache
def simple_decorator(func):
def wrapper(*args, **kwargs):
#check cache
print("simple decorator")
func(*args, **kwargs)
#set cache
return wrapper
class AbstractInput(object):
def __init__(self, cacheparams = {'maxsize': 10, 'ttl': 300}):
self.cache = TTLCache(**cacheparams)
super().__init__()
@simple_decorator
def retrieve(self, params):
print("AbstractInput retrieve")
raise NotImplementedError("AbstractInput inheritors must implement retrieve() method")
class JsonInput(AbstractInput):
def retrieve(self, params):
print("JsonInput retrieve")
return json.dumps(params)
class SillyJsonInput(JsonInput):
def retrieve(self, params):
print("SillyJsonInput retrieve")
params["silly"] = True
return json.dumps(params)
Run Code Online (Sandbox Code Playgroud)
实际结果: …
inheritance metaclass python-3.x python-decorators class-decorator
python ×4
inheritance ×2
metaclass ×2
abstract ×1
class ×1
decorator ×1
python-2.7 ×1
python-3.x ×1