В Python, как я могу указать, что я переопределяю метод?
в Java, например,@Override аннотация не только обеспечивает проверку времени компиляции переопределения, но и обеспечивает отличный самодокументированный код.
Я просто ищу документацию (хотя если это индикатор для какой-то проверки, например pylint, это бонус). Я могу добавить комментарий или docstring где-нибудь, но каков идиоматический способ указать переопределение в Python?
7 ответов:
обновление (23.05.2015): на основе этого и ответа fwc: s Я создал установочный пакет piphttps://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!!!!!!!
вот реализация, которая не требует спецификации имени 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
Если вы хотите это только для целей документации, вы можете определить свой собственный переопределить декоратор:
def override(f): return f class MyClass (BaseClass): @override def method(self): passэто действительно не что иное, как глазная конфета, если вы не создадите переопределение(f) таким образом, что фактически проверяет переопределение.
но тогда, это Python, зачем писать его так, как это было Java?
Python-это не Java. Конечно, на самом деле нет такой вещи, как проверка времени компиляции.
Я думаю, что комментарий в docstring-это много. Это позволяет любому пользователю вашего метода ввести
help(obj.method)и видим, что метод переопределен.вы также можете явно расширить интерфейс с
class Foo(Interface), что позволит пользователям вводитьhelp(Interface.method)чтобы получить представление о функциональности вашего метода предназначен для обеспечения.
насколько я знаю, нет специального способа указать переопределение в Python. Вы просто определяете метод и включаете строку документа, как всегда.
Как и другие сказали, в отличие от Java нет тега @Overide, однако выше вы можете создать свой собственный с помощью декораторов, однако я бы предложил использовать глобальный метод getattrib () вместо использования внутреннего dict, чтобы вы получили что-то вроде следующего:
def Override(superClass): def method(func) getattr(superClass,method.__name__) return methodЕсли бы вы хотели, чтобы вы могли поймать getattr () в своей собственной попытке поймать свою собственную ошибку, но я думаю, что метод getattr лучше в этом случае.
также это ловит все элементы, привязанные к классу в том числе методы класса и vairables
Hear прост и работает под 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()
Comments