例如,在Java中,@Override注释不仅提供了覆盖的编译时检查,而且还提供了优秀的自写文档代码。我只是在寻找文档(尽管如果它是像pylint这样的检查器的指示器,那是一个奖励)。我可以在某处添加注释或文档字符串,但是在Python中指示重写的惯用方式是什么?在Python中,我如何表明我重写了一个方法?
回答
更新(2015年5月23日):在此基础上与FWC:的答案我创建了一个点子安装包https://github.com/mkorpela/overrides
时不时我会在这里结束看这个问题。 主要发生在(再次)看到我们的代码库中的相同错误后:有人已经忘记了一些实现类的“接口”,同时在“接口”中重命名方法..
那么,Python不是Java,但Python已权力 - 而且明确比隐含更好 - 在现实世界中,这件事情会对我有所帮助。
所以这里是覆盖装饰器的草图。这将检查作为参数给出的类与正在装饰的方法具有相同的方法(或其他)名称。
如果您能想到更好的解决方案,请在此发布!
def overrides(interface_class):
def overrider(method):
assert(method.__name__ in dir(interface_class))
return method
return overrider
其工作原理如下:
class MySuperInterface(object):
def my_method(self):
print 'hello world!'
class ConcreteImplementer(MySuperInterface):
@overrides(MySuperInterface)
def my_method(self):
print 'hello kitty!'
,如果你做了错误的版本,它将类加载过程中引发断言错误:
class ConcreteFaultyImplementer(MySuperInterface):
@overrides(MySuperInterface)
def your_method(self):
print 'bye bye!'
>> AssertionError!!!!!!!
据我所知,在Python中没有特别的方式来表示重写。您只需定义方法并像往常一样包含文档字符串。
Python不是Java。编译时检查当然没有这样的事情。
我认为在文档字符串中的评论很多。这允许您的方法的任何用户键入help(obj.method)
并查看该方法是一个覆盖。
您还可以使用class Foo(Interface)
明确扩展接口,这将允许用户输入help(Interface.method)
以了解您的方法旨在提供的功能。
Java中`@ Override`的真正意义在于不会记录文件 - 当你打算重写一个方法时,会发现一个错误,但最终会定义一个新文件(例如,因为拼写错了一个名称;在Java中,它可能会也因为您使用了错误的签名而发生,但这在Python中不是问题 - 但拼写错误仍然存在)。 – 2009-07-22 19:35:00
如果你想这样的文档,仅供参考,您可以定义自己的覆盖装饰:
def override(f):
return f
class MyClass (BaseClass):
@override
def method(self):
pass
这真的不算什么,但养眼的,除非你创建倍率(F)以这样一种方式,是实际上检查覆盖。
但是,这是Python,为什么写它像Java?
这里有没有一个实现需要指定interface_class名称。
import inspect
import re
def overrides(method):
# actually can't do this because a method is really just a function while inside a class def'n
#assert(inspect.ismethod(method))
stack = inspect.stack()
base_classes = re.search(r'class.+\((.+)\)\s*\:', stack[2][4][0]).group(1)
# handle multiple inheritance
base_classes = [s.strip() for s in base_classes.split(',')]
if not base_classes:
raise ValueError('overrides decorator: unable to determine base class')
# stack[0]=overrides, stack[1]=inside class def'n, stack[2]=outside class def'n
derived_class_locals = stack[2][0].f_locals
# replace each class name in base_classes with the actual class type
for i, base_class in enumerate(base_classes):
if '.' not in base_class:
base_classes[i] = derived_class_locals[base_class]
else:
components = base_class.split('.')
# obj is either a module or a class
obj = derived_class_locals[components[0]]
for c in components[1:]:
assert(inspect.ismodule(obj) or inspect.isclass(obj))
obj = getattr(obj, c)
base_classes[i] = obj
assert(any(hasattr(cls, method.__name__) for cls in base_classes))
return method
像其他人说,Java不同没有@Overide标签上方。然而,你可以创建自己使用的装饰,但是我会建议使用getattrib()全局法,而不是使用内部字典所以你喜欢的东西以下内容:
def Override(superClass):
def method(func)
getattr(superClass,method.__name__)
return method
如果你想你能赶上GETATTR()在自己的尝试捕捉提高自己的错误,但我认为GETATTR方法是在这种情况下更好。
另外这款捕捉必然包括类方法的类的所有项目和vairables
听到的是最简单和Jython下工作的Java类:
class MyClass(SomeJavaClass):
def __init__(self):
setattr(self, "name_of_method_to_override", __method_override__)
def __method_override__(self, some_args):
some_thing_to_do()
- 1. 对一个错误monad证明了一些monad法我写了
- 2. Python 3.3导入一个类我写了
- 3. 为什么我无法在python中重写此方法?
- 4. 如何编写一个方法来在python中创建sqlite表
- 5. c#这是我如何重写方法?
- 6. 我如何在Oxygene中声明一个全局方法
- 7. 我正在使用servlet,只有一个deGet和DoPost方法。我写了一个新的方法。 。我如何直接访问新的方法?
- 8. 如何在我编写的JavaScript中重构Ruby的#{}方法
- 9. 我不明白如何在我的类中的方法在JAVA
- 10. 我在另一个类中创建了一个方法,但是我无法在主类中使用onClick方法
- 11. 我如何重写这个循环中,更有效的方式在Python
- 12. 在Python中,如何确定在哪个类中声明了方法?
- 13. 我可以用特征中的方法重写一个scala类方法吗?
- 14. 我在$(document).ready()中写了两个ajax函数。我的html页面的方法
- 15. 在Python中重写“+ =”? (__iadd __()方法)
- 16. 我如何重写一个宝石添加到ActiveRecord :: Base的类方法(在我的装饰器中)
- 17. 如何在java中调用一个级别的重写方法?
- 18. 当我CSV写我如何在Python
- 19. 如何让MySQL Workbench忘记我重命名了一个表?
- 20. 我可以重写一个方法在RSpec只有一个参数调用
- 21. 当我重写一个方法时,什么是异常
- 22. pyqt4:我可以重写一个没有子类的方法吗?
- 23. 我在PHP中声明了哪些静态方法/变量?
- 24. 我如何在Scala中声明创建一个列表?
- 25. 我该如何声明一个mixin方法,使它可以在实例方法和类方法中使用?
- 26. 我想知道如何在Python中重复一个过程?
- 27. 为什么我不能在另一个UIViewController中重写UIViewController的扩展方法?
- 28. 如何在python中重写方法默认参数?
- 29. 如何在Python中重写PySerial的“__del__”方法?
- 30. 重写的Python Mechanize.Browser.open()方法
换句话说,你永远不表明你压倒一种方法?让读者自己弄清楚这一点? – Bluu 2009-07-22 23:49:43
是的,我知道它似乎是一种来自编译语言的容易出错的情况,但您只需接受它。在实践中,我没有发现它是一个很大的问题(在我的情况下,Ruby,而不是Python,但同样的想法) – 2009-07-23 17:12:55
当然,完成。 Triptych的答案和mkorpela的答案都很简单,我喜欢这个,但是后者的明显超越隐含的精神,并且明显地防止错误获胜。 – Bluu 2013-10-17 16:07:47