如何声明哪些方法可以应用于哪些对象

时间:2016-02-09 14:11:51

标签: python python-2.7 inheritance architecture

我正在编写一个服务器应用程序,该功能通过RPC调用。应用程序具有可以相互交互的对象。

假设以下简化示例:

  • 一个人可以检查和修理,并且可以进行检查;
  • 汽车可以制动,可以检查和固定。

直接实施¹(RPC超出范围):

class Car(object):
    def __init__(self, broken=False):
        self.name = 'car'
        self.broken = broken

    def breaks(self):
        self.broken = True
        print 'Car broke'

    def inspected(self, by):
        if by.pro:
            if self.broken:
                print '{}: It\'s a broken car'.format(by.name)
            else:
                print '{}: It\'s a working car'.format(by.name)
        else:
            print '{}: It\'s a car'.format(by.name)

    def fixed(self, by):
        if not self.broken:
            print 'Car is not broken'
        else:
            self.broken = False
            print by.name, 'fixed the car'


class Person(object):
    def __init__(self, name, pro=False):
        self.name = name
        self.pro = pro

    def inspect(self, target):
        target.inspected(by=self)

    def fix(self, target):
        target.fixed(by=self)

    def inspected(self, by):
        if self.pro:
            print '{}: {} is a pro'.format(by.name, self.name)
        else:
            print '{}: {} is not a pro'.format(by.name, self.name)

创建一些对象:

>>> car = Car()
>>> john = Person('John', pro=True)
>>> bob = Person('Bob', pro=False)

现在,用户可以与他们进行互动²

>>> car.breaks()
'Car broke'
>>> john.inspect(car)
"John: It's a broken car"
>>> john.fix(car)
'John fixed the car'
>>> bob.inspect(john)
'Bob: John is a pro'

这里的问题是,如果我们拨打john.fix(bob),我们就会获得AttributeError: 'Person' object has no attribute 'fixed'

那么,声明/限制哪些方法可以应用于哪些对象的好和/或'pythonic'方法是什么?

到目前为止,我提出了以下想法:

  1. 创建一个膨胀的基础(抽象)类,它将包含所有可能方法和属性的存根。这里的缺点是,随着项目的增长和新方法的增加,它应该单独更新;并且所有子课程都会有很多不相关和未使用过的东西。此外,并没有真正解决问题。
  2. 使用try...except传送所有来电。看起来不稳定和'pythonic',并没有解决问题。
  3. 手动指定方法支持的类。随着项目的增长而无法维护,并且没有严格说明目标类必须具有哪些属性。
  4. 多重继承。使用fix方法创建新的FixAllRobot类时,我们可能忘记添加目标检查所需的pro属性,从而解决了#3的问题。缺点:class Person(Inspecter, Fixer, ..., TwentyMoreOneFunctionHolder)看起来不值得信赖和可读。我们仍然需要检查是否可以在目标上使用操作。
  5. 非常像#4,但也继承了目标端类。缺点:继承地狱:class Person(Inspecter, CanBeInspected, Fixer, ..., FortyMoreOneFunctionHolder)。优点:看起来像一个解决方案。
  6. 注意:

    1. 关于检查和检查(以及其他操作对):对象和主题都有一些依赖于类的操作,必须在调用操作时进行。

    2. 现在,同一类的所有对象都存储在其类字典中,其id为key。 Meta类跟踪创建的类。用户通常只能控制一个对象。当用户发送可能看起来像{"jsonrpc": "2.0", "id": 77, "method": "inspect", "params": {"target": "car", "id": 1}}的RPC请求(实际上是json-rpc)时,target被解析为目标类,id被解析为实例标识符。某些可选参数也可能通过params dict。

    3. 传递

      旁注:我知道QT信号槽系统,并喜欢它,但我认为情况并非如此。

      Sidenote2:我坚持使用python 2.7

1 个答案:

答案 0 :(得分:1)

我建议使用try...except方法。 EAFP("更容易请求宽恕而不是许可")是根据https://docs.python.org/2/glossary.html#term-eafp认为的pythonic。随着项目的发展,它也可以很好地扩展。