简体   繁体   English

为一堆 static 方法提供命名空间的最佳实践是什么?

[英]What is the best practice to give a namespace for a bunch of static methods?

I need a namespace within a module for many different static methods doing similar jobs.我需要一个模块中的命名空间,用于执行类似工作的许多不同 static 方法。 From my research I learnt that having a class full of static methods is considered anti-pattern in Python programming:从我的研究中我了解到,在 Python 编程中,拥有一个充满 static 方法的 class 被认为是反模式:

class StatisticsBundle:
  @staticmethod
  def do_statistics1(params):
     pass

  @staticmethod
  def do_statistics2(params):
     pass

If this isn't a good solution, what is the best practice instead that allows me to do a namespace lookup like getattr(SomeNameSpace, func_name) within the same module?如果这不是一个好的解决方案,那么最好的做法是什么?它允许我在同一个模块中进行类似getattr(SomeNameSpace, func_name)的命名空间查找?

Use a package.使用 package。 Place the functions in a separate module, without using a class.将函数放在单独的模块中,而不使用 class。

Within the statistics folder on your computer define 2 modules:在您计算机上的统计文件夹中定义 2 个模块:

  1. helpers.py where you define the helper functions. helpers.py用于定义辅助函数。
  2. __init__.py where you write the bulk of your code. __init__.py用于编写大部分代码的地方。

You may rename the helpers module, if you can come up with a better name for the group of functions you define within it.如果您可以为您在其中定义的一组函数想出一个更好的名称,您可以重命名helpers模块。 However, the __init__ module of a package is special.但是,package 的__init__模块是特殊的。 When the package is imported, the __init__ module is given the package name and evaluated.当 package 被导入时, __init__模块被赋予 package 名称并被评估。

To apply your example:要应用您的示例:

#statistics\helpers.py

def do_statistics1(params):
     pass

def do_statistics2(params):
     pass

# Rest of module omitted
#statistics\__init__.py
# Relative import
from . import helpers
# Get function using getattr()
do_statistics1 = getattr(helpers, "do_statistics1")
# Get function using dot notation
do_statistics2 = helpers.do_statistics2

# Rest of module omitted

Be sure to test the package by importing it.请务必通过导入来测试 package。 Relative imports do not work when evaluating a module within a package.评估 package 中的模块时,相对导入不起作用。

In conclusion, you can get attributes from a module just like you can from a class.总之,您可以像从 class 中一样从模块中获取属性。

[...] what is the best practice instead that allows me to do a namespace lookup like getattr(SomeNameSpace, func_name) within the same module? [...] 最佳getattr(SomeNameSpace, func_name)是什么?

Python functions are first-class functions . Python 函数是一流的函数 Hence, the simplest namespace is a dict (which actually isn't far from how instance namespaces work on __dict__ ).因此,最简单的命名空间是dict (实际上与实例命名空间在__dict__上的工作方式相距不远)。 If you want to implement a sort of factory function, it's just:如果你想实现一种工厂 function,它只是:

def _create_foo():
    return Foo(...)

def _create_bar():
    return Bar(...)


_my_ns = {
    'foo': _create_foo,
    'bar': _create_bar,
}

def my_factory(name):
    return _my_ns[name]()

Also in runtime (given how staticmethod descriptor works in Python 3) they will be of the same types.FunctionType .同样在运行时(考虑到staticmethod方法描述符在 Python 3 中的工作方式)它们将具有相同的types.FunctionType

>>> class ns:
...     
...     @staticmethod
...     def foo():
...         pass
... 
... type(ns.foo)
<class 'function'>
>>> type(_my_ns['foo'])
<class 'function'>

Depending on your python version, you might be able to use a SimpleNamespace根据您的 python 版本,您可能可以使用SimpleNamespace

import types

def foo():
    print("foo")

def bar():
    print("bar")

namespace = types.SimpleNamespace(foo=foo, bar=bar)
namespace.foo()
namespace.bar()

I need a namespace within a module for many different static methods doing similar jobs.我需要一个模块中的命名空间,用于执行类似工作的许多不同 static 方法。 From my research I learnt that having a class full of static methods is considered anti-pattern in Python programming:从我的研究中我了解到,在 Python 编程中,拥有一个充满 static 方法的 class 被认为是反模式:

class StatisticsBundle:
  @staticmethod
  def do_statistics1(params):
     pass

  @staticmethod
  def do_statistics2(params):
     pass

If this isn't a good solution, what is the best practice instead that allows me to do a namespace lookup like getattr(SomeNameSpace, func_name) within the same module?如果这不是一个好的解决方案,那么最好的做法是什么?它允许我在同一个模块中进行类似getattr(SomeNameSpace, func_name)的命名空间查找?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM