简体   繁体   中英

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. From my research I learnt that having a class full of static methods is considered anti-pattern in Python programming:

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?

Use a package. Place the functions in a separate module, without using a class.

Within the statistics folder on your computer define 2 modules:

  1. helpers.py where you define the helper functions.
  2. __init__.py where you write the bulk of your code.

You may rename the helpers module, if you can come up with a better name for the group of functions you define within it. However, the __init__ module of a package is special. When the package is imported, the __init__ module is given the package name and evaluated.

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. Relative imports do not work when evaluating a module within a package.

In conclusion, you can get attributes from a module just like you can from a class.

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

Python functions are first-class functions . Hence, the simplest namespace is a dict (which actually isn't far from how instance namespaces work on __dict__ ). If you want to implement a sort of factory function, it's just:

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 .

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

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. From my research I learnt that having a class full of static methods is considered anti-pattern in Python programming:

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?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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