[英]Python 2.7 — Calling an Abstract Base Class' method from an Instance
我正在从注册为ABC子类的类的实例中寻找调用抽象基类方法的正确方法。 这是一些非常基本的测试代码,首先需要弄清楚如何使它工作。 我现在在这里:
from abc import ABCMeta
# Dog class
class Dog(object):
def speak(self):
pass
def move(self):
pass
# Barking behaviors
class Bark(object):
__metaclass__ = ABCMeta
def speak(self):
print "bark bark bark"
class Howl(object):
__metaclass__ = ABCMeta
def speak(self):
print "ahwoooooo"
# Movement behaviors
class Run(object):
__metaclass__ = ABCMeta
def move(self):
print "I'm running"
class Walk(object):
__metaclass__ = ABCMeta
def move(self):
print "I'm walking"
# Dog implementations
class Beagle(Dog):
pass
Howl.register(Beagle)
Run.register(Beagle)
nora = Beagle()
nora.speak() # THIS IS THE ISSUE: Calls speak() from original Dog class
nora.move() # Need to call move() from registered ABC
# Test to be sure .register() was used properly
assert isinstance(nora, Howl)
虽然此方法似乎过于涉及更改两种Dog方法,但我希望能够灵活地将行为分配给未知数量的实例。 我希望能够在不知道实际行为的情况下调用speak()和move()。 我也喜欢这种方法,因为我可以轻松删除或更改类注册的行为,而无需更改任何现有代码。
当前代码读取方式nora.speak()和nora.move()调用从Dog到Beagle的继承方法,这些方法仅包含pass。
如果有人从那时起对我需要做什么以使已注册的行为的方法可调用,或者我的方法完全有缺陷,我将不胜感激。
这是我的尝试(可能不是最Python的方式,但与您的帖子相似):
class Animals(object):
def speak(self):
return self.speak_action
def swim(self):
return self.swim_action
def move(self):
return self.move_action
class Dog(Animals):
@property
def speak_action(self):
return "bark bark bark"
@property
def move_action(self):
return "I'm Running"
class Beagle(Dog):
@property
def speak_action(self):
return "ahwoooooo"
class Duck(Animals):
@property
def swim_action(self):
return "Im floating"
@property
def speak_action(self):
return "Quack!!"
@property
def move_action(self):
return "I Fly!"
class Mallard(Duck):
@property
def speak_action(self):
return "I'm Flying higher"
(最好的做法是让异常冒出来)
In [825]: d = Dog()
In [826]: d.speak()
Out[826]: 'bark bark bark'
In [827]: d.move()
Out[827]: "I'm Running"
In [828]: d.swim()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-828-c6d2ef2b464d> in <module>()
----> 1 d.swim()
.stuff/python/git_py/help_so.py in swim(self)
4
5 def swim(self):
----> 6 return self.swim_action
7
8 def move(self):
AttributeError: 'Dog' object has no attribute 'swim_action'
您可以选择要委派的内容:
In [830]: b = Beagle()
In [831]: b.speak()
Out[831]: 'ahwoooooo'
In [832]: b.move()
Out[832]: "I'm Running"
In [833]: b.swim()
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-833-9c7b1a0c0dca> in <module>()
----> 1 b.swim()
/stuff/python/git_py/help_so.py in swim(self)
4
5 def swim(self):
----> 6 return self.swim_action
7
8 def move(self):
AttributeError: 'Beagle' object has no attribute 'swim_action'
并创建其他具有更多技能的动物:
In [849]: dd = Duck()
In [850]: dd.speak()
Out[850]: 'Quack!!'
In [851]: dd.move()
Out[851]: 'I Fly!'
In [852]: dd.swim()
Out[852]: 'Im floating'
您可以将事情特定于单个类,甚至是默认类,也可以特定于主类,并且可以根据需要扩展。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.