每次在课堂上调用函数的最佳方法是什么?

时间:2015-02-27 11:31:40

标签: python design-patterns

我有一个具有可选功能的类作为参数。有时我用函数创建这个类的实例,有时候不是。

每次调用实例的某些方法时都会调用该函数。当然,如果没有给出功能,那里什么也没发生。

我的问题是,实现这一目标的最佳方法是什么?我尝试了几件事。您能否通过性能,可扩展性和可读性来判断我的解决方案?你有更好的解决方案吗?

该课程看起来像这样

class MyClass(...):
    def __init__(self, function=None):
        self.function = function

    def method_a(self, ...)
        ...
        self.function(a,b,c)
        ...

    def method_b(self, ...)
        ...
        self.function(a,b,c)
        ...

    def method_c(self, ...)
        ...
        #not every method bothers with the function
        ...

当然这会产生

TypeError: 'NoneType' object is not callable

最天真的解决方案是通过防御性ifs或试验改变课程本身:

class MyClass(...):
    def __init__(self, function=None):
        self.function = function

    def method_a(self, ...)
        ...
        if self.function:
            self.function(a,b,c)
        ...

    def method_b(self, ...)
        ...
        if self.function:
            self.function(a,b,c)
        ...

第二个解决方案是创建一个无任何功能,并可能将其存储在self.function

def do_nothing(*x):
    pass

class MyClass(...):
    def __init__(self, function=None):
        if function is None:
            function = do_nothing
        self.function = function

    def method_a(self, ...)
        ...
        self.function(a,b,c)
        ...

    def method_b(self, ...)
        ...
        self.function(a,b,c)
        ...

第三种解决方案是在其中创建一个具有防御性ifs的函数包装器:

class Maybe(object):
    def __init__(self, function=None):
        self.function = function

    def __call__(self, *args):
        if self.function is None:
            return
        # else
        return self.function(args)

class MyClass(...):
    def __init__(self, function=None):
        self.function = Maybe(function)

    def method_a(self, ...)
        ...
        self.function(a,b,c)
        ...

    def method_b(self, ...)
        ...
        self.function(a,b,c)
        ...

1 个答案:

答案 0 :(得分:2)

除非您发现瓶颈并且可以衡量,否则每个人都会告诉您,性能不应该影响您的代码设计。重要的是代码可读性。

在每次调用之前添加if条件是可读但重复的。重复性任务通常包含在一个简单的函数中,为什么不这样做呢?

class MyClass(object):
    def __init__(self, function=None):
        self._function = function

    def method(self):
        self._callFunction("Charlie")

    def _callFunction(self, *args, **kwargs):
        if self._function:
            self._function(*args, **kwargs)

def myFunction(name):
    print("Je suis %s" % name)

instance = MyClass(myFunction)
instance.method()