[英]How to require implementation of method in Python?
我在Python中使用鸭子输入。
def flagItem(object_to_flag, account_flagging, flag_type, is_flagged):
if flag_type == Flags.OFFENSIVE:
object_to_flag.is_offensive=is_flagged
elif flag_type == Flags.SPAM:
object_to_flag.is_spam=is_flagged
object_to_flag.is_active=(not is_flagged)
object_to_flag.cleanup()
return object_to_flag.put()
在其中将不同的对象作为object_to_flag
传入时,所有对象均具有is_active
, is_spam
和is_offensive
属性。 它们也碰巧具有cleanup()
方法。
我要传递的对象都具有相同的基类(它们是Google App Engine中的db对象):
class User(db.Model):
...
is_active = db.BooleanProperty(default = True)
is_spam = db.BooleanProperty(default=False)
is_offensive = db.BooleanProperty(default=False)
def cleanup():
pass
class Post(db.Model):
...
is_active = db.BooleanProperty(default = True)
is_spam = db.BooleanProperty(default=False)
is_offensive = db.BooleanProperty(default=False)
def cleanup():
pass
如何使cleanup()
方法抽象化,以便可以为所有需要孩子提供实现的对象提供相同的父类?
也许更重要的是,这是“ pythonic”吗? 我应该走这条路,还是只依靠鸭子的打字? 我的背景是Java,我正在尝试学习Python的做事方式。
谢谢!
如果要确保实现清除方法,则可以使用@abc.virtualmethod
装饰器进行包装。 这将在实例化尚未覆盖虚拟方法的任何对象时导致错误。 这还要求您将abc.ABCMeta
类的__metaclass__
。
有关更多信息和一些示例,请参见abc模块 。
这通常不做:通常只有文档说明实现者必须重写给定的方法。 但是,这可能更多是由于abc
模块(Python 2.6中的新增功能)的新颖性,而不是这种方法的非Python性。
为什么没有在调用cleanup
方法时引发NotImplementedError
? 如果他们想让您的孩子上课,他们将不得不采取某种实施措施。
由于您没有可用的abc,因此可以使用简单的元类来完成此操作
class Abstract(type(db.Model)):
def __new__(metacls, clsname, bases, clsdict):
for methodname in clsdict.pop('_abstract_methods_', []):
try:
if not callable(clsdict[methodname]):
raise TypeError("{0} must implement {1}".format(clcname, methodname))
except KeyError:
raise TypeError("{0} must implement {1}".format(clcname, methodname))
return super(Abstract, metacls).__new__(metacls, clsname, bases, clsdict)
class RequireCleanup(db.Model):
__metaclass__ = Abstract
_abstract_methods_ = ['cleanup']
def cleanup(self):
pass
表达式type(db.Model)
解析为用于db.Model
任何元类,因此我们不会踩Google的代码。 此外,我们弹出_abstract_methods_
出类字典之前得到它的传递给谷歌的__new__
方法,这样我们就不会破坏任何东西。 如果db.Model
已经具有使用该名称的属性,则需要将其更改为其他名称。
尽管我从未亲自使用过它,但我已经看到了许多有关Zope接口的参考。 这对于您的任务来说可能是多余的,但可能会为您提供一些指导。 对于具有Java背景的人来说可能会感到很舒服。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.