别名要从 init 方法分配的 class 函数

Aliase a class function to be assigned from init method

假设我有一个 class 例如:

class Model(object):
    def __init__(self, foo = 'bar'):
        if foo == 'bar':
            self.f = self._sse
        else:
            self.f = None

    def _sse():
        pass

有没有一种方法可以创建别名,这样我就不必检查非位置参数的值是什么 foo?像

class Model(object):
    alias = {'bar': _sse}
    def __init__(self, foo = 'bar'):
        self.f = foo

    def _sse():
        pass

技术答案:您可以通过在 初始化器 之前定义目标函数来实现,将此函数作为默认参数引用(Python 函数也是对象),并在目标函数上手动调用描述符协议:

>>> class Model(object):
...     def _sse(self):
...         print("in self._sse")
...     def __init__(self, foo=_sse):
...         self.f = foo.__get__(self, type(self))
... 
>>> m = Model()
>>> m.f()
in self._sse

请注意,使用此解决方案,如果您想传递另一个函数,此函数必须将 self 作为第一个参数:

>>> # doesn't work
... def bar(): print("bar")
... 
>>> m2 = Model(bar)
>>> m2.f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bar() takes no arguments (1 given)
>>> # works:
... def baaz(self): print("baaz({})".format(self))
... 
>>> m3 = Model(baaz)
>>> m3.f()
baaz(<__main__.Model object at 0x7fc3e2337090>)

现在从可读性 POV 来看,恕我直言,这几乎算不上改进……

编辑:正如 Aran-Fey 所提到的,这并不能完全回答问题,因此对于更多 "literal" 版本(并且不需要特殊定义排序等):

class Model(object):
    def _sse(self):
        print("in self._sse")

    alias = {"bar": "_sse"}

    def __init__(self, foo="bar"):
        self.f = getattr(self, self.alias.get(foo, "___"), None)

但这仍然没有提高可读性...

使用@KlausD。建议并在 __init__ 方法中包含 alias 对我有用。

class Model(object):
    def __init__(self, foo = 'bar'):
        alias = {'bar': self._sse,
                 'bar2': self._sse2}

        self.f = alias.get(foo)

    def _sse(self):
        print('in sse')
    def _sse2(self):
        print('in sse2')


m = Model(foo='bar')
m.f() # in sse
m = Model(foo='bar2')
m.f() # in sse2