【问题标题】:What is the best way to perhaps call a function, every time, inside a class?每次在类中调用函数的最佳方法是什么?
【发布时间】:2015-04-30 02:37:30
【问题描述】:

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

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

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

类是这样的

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

最天真的解决方案是用防御性的 if 或试验来改变类本身:

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)
        ...

第三种解决方案是创建一个包含防御性 if 的函数包装器:

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)
        ...

【问题讨论】:

  • 我会说,第二个。只需添加一个默认参数:__init__(self, function=lambda *x: None)
  • @georg,它不能很好地扩展。在我的示例中,我有 1 个条件函数,但这并不意味着我的程序中有 1 个。
  • 你必须更具体。您正在解决的实际问题是什么?在不知道所有细节的情况下,我们只能推测。

标签: python design-patterns


【解决方案1】:

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

在每次调用之前添加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()

【讨论】:

  • 它的扩展性不是很好,我无法想象自己为每个条件函数编写一个额外的方法。
  • 你没有在你的问题中提到任何这样的事情。而且我实际上不确定你在那之后是什么?我的回答中的MyClass 类可以采用您可能决定传递的任何函数,因此可以使用任何可能的参数组合——这不是您要找的吗?它应该以哪种方式扩展?你想让你的类MyClass 包含多个方法吗?
猜你喜欢
  • 2016-09-19
  • 1970-01-01
  • 1970-01-01
  • 2017-07-16
  • 2013-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多