Python中的类,方法和多态

Mor*_*ock 3 python oop polymorphism timer

我制作了一个模块原型,目的是在python中构建复杂的计时器计划.类原型模拟Timer对象,每个对象具有等待时间,重复对Timer和其他Repeat对象进行分组的对象,以及Schedule类,仅用于保存整个构造或Timers和Repeat实例.建筑可以根据需要复杂化,并且需要灵活.

这三个类中的每一个都有一个.run()方法,允许完成整个计划.无论是什么类,该.run()方法要么运行计时器,要么运行一定数量的迭代重复组,要么运行计划.

这种面向多态的方法听起来还是愚蠢的?我应该考虑采用哪些其他适当的方法来构建这样一个多功能的实用程序,允许将所有构建块放在一起,以简单的方式将所有构建块组合在一起?

谢谢!

这是模块代码:

#####################
## Importing modules

from time import time, sleep


#####################
## Class definitions

class Timer:
    """
    Timer object with duration.

    """
    def __init__(self, duration):
        self.duration = duration
    def run(self):
        print "Waiting for %i seconds" % self.duration
        wait(self.duration)
        chime()

class Repeat:
    """
    Repeat grouped objects for a certain number of repetitions.

    """
    def __init__(self, objects=[], rep=1):
        self.rep = rep
        self.objects = objects
    def run(self):
        print "Repeating group for %i times" % self.rep
        for i in xrange(self.rep):
            for group in self.objects:
                group.run()

class Schedule:
    """
    Groups of timers and repetitions. Maybe redundant with class Repeat.

    """
    def __init__(self, schedule=[]):
        self.schedule = schedule
    def run(self):
        for group in self.schedule:
            group.run()

########################
## Function definitions

def wait(duration):
    """
    Wait a certain number of seconds.

    """
    time_end = time() + float(duration) #uncoment for minutes# * 60
    time_diff = time_end - time()
    while time_diff > 0:
        sleep(1)
        time_diff = time_end - time()

def chime():
    print "Ding!"
Run Code Online (Sandbox Code Playgroud)

Tor*_*rek 5

基于鸭子的方法很好.如果您希望能够检查给定的类是否应该在您的框架中运行,那么您可以使用抽象基类(需要Python 2.6).PEP 3119规定:

[...]有许多不同的方法来测试对象是否符合特定协议.例如,如果询问'这个对象是一个可变序列容器吗?',可以查找'list'的基类,或者可以查找名为' getitem ' 的方法.但请注意,尽管这些测试看似显而易见,但它们都不正确,因为一个产生假阴性,另一个产生假阳性.[...]本PEP提出了一种特殊的策略来组织这些测试,称为抽象基类,或者ABC.ABCs只是Python类,它们被添加到对象的继承树中,以向外部检查器发送该对象的某些特征.使用isinstance()进行测试,并且特定ABC的存在意味着测试已通过.

您可以实现ABC并使用isinstanceissubclass测试是否为您的框架编写类或实例:

from abc import ABCMeta, abstractmethod

class Runnable(object):
    __metaclass__ = ABCMeta

    @abstractmethod
    def run(self):
        raise NotImplementedError

 class Schedule(Runnable):
     ...
Run Code Online (Sandbox Code Playgroud)

重要的一点是,也可以将其他类(您可能无法控制,因为您没有编写它们)注册为runnables,isinstance并且issubclass方法将反映出:

  >>> issubclass(SomeOtherClass, Runnable)
  False
  >>> Runnable.register(SomeOtherClass)
  >>> issubclass(SomeOtherClass, Runnable)
  True
Run Code Online (Sandbox Code Playgroud)