【问题标题】:python: stateless function library designpython:无状态函数库设计
【发布时间】:2012-01-22 06:02:04
【问题描述】:

我正在构建一个包含各种功能的库,这些功能将在项目中经常被重用。每个函数都是无状态的(在创建时不需要参数,也没有任何内存)。有些函数使用其他函数。

这些函数将作为参数传递给项目的其余部分。

以下哪种方法更好?

1.将所有函数定义为某个模块中的全局函数:

def f1(x):
  # use x

def f2(x):
  # use x and f1

2.将所有函数定义为类中的方法,并根据用途将类按层次排列:

class F1:
  def __call__(x):
    # use x

f1 = F1()

class F2(F1):
  def __call__(x):
    # use x and f1

f2 = F2()

我什至考虑选项 2 的原因是我的一些函数有一些共同点。例如,函数f2、f3、f11 都以调用f1 开始。我在想我可能想做这样的事情:

class F1:
  def __call__(self, x):
     self.f1(x)
     self.calc(x)
  def f1(self, x):
     # do something
  # don't define calc here; F1 is abstract base class 

class F2(F1):
  def calc(self, x):
     # do something

class F3(F1):
  def calc(self, x):
     # do something

【问题讨论】:

  • 你是从哪里想到要做 2 的?
  • @FrancisAvila:查看我更新的问题来解释我的想法。
  • 您的意思是让F2 和F3 扩展F1?这不是代码所说的......

标签: python python-3.x


【解决方案1】:

选项 1 要简单得多。选项 2 太复杂了!!

另一个可能使测试更容易的建议:

1.1。将它们全部定义为一个模块中单个类的方法。酌情使用@staticmethod 和@classmethod 装饰器。这可以使它们更容易被模拟替换或通过稍后提供新类或子类来覆盖替代实现。

spam.py:

class Spam(object):
  @staticmethod
  def f1(x):
    # use x

  @classmethod
  def f2(cls, x):
    # use x and cls.f1

这仍然更复杂,因此您可能只想坚持使用选项 1,直到您对上述内容有需求。

【讨论】:

  • 您使用@classmethod 提出的建议与我的想法相似。我不想强迫所有东西都是@classmethod,因为我想有一天我可能想给一个函数添加一个状态;既然我正在编写课程,为什么不为潜在的需求留出灵活性呢?
  • 如果需要有状态,有一些方法可以用类或对象替换函数,而无需更改 API。
  • @kindall:是的。我没有想到这一点。这很简单,只需使用__call__?
  • 对于一个类,您可以通过以下两种方式之一进行操作:在类上使用__call__,然后在类定义之后立即实例化对象并将其分配给您之前使用的名称功能。然后实例可以像函数一样调用。或者您可以使用元类来覆盖类本身的__call__ 行为。状态也可以使用不确定的生成器而不是类来维护,这可以与只在生成器上调用 next() 的可调用函数相结合。
  • 这里有一些你可能会感兴趣的东西(更新):pastebin.com/TMVaqeFm
【解决方案2】:

如果您需要多个函数在开始和/或结束时执行一些公共代码,您可以将公共代码放在装饰器中,如explained here。

【讨论】:

    【解决方案3】:

    如果您不在类中存储数据,如果这些是无状态函数,您就不会这样,我看不出使用它们有任何意义。 Python 允许您在模块级别精确定义函数,这样您就不必使用类,除非您确实需要类的功能。

    【讨论】:

      猜你喜欢
      • 2011-01-07
      • 1970-01-01
      • 2021-01-02
      • 2021-02-12
      • 1970-01-01
      • 2014-10-20
      • 2011-02-12
      • 1970-01-01
      • 2011-11-17
      相关资源
      最近更新 更多