Étant donné que j'ai une classe telle que:

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

    def _sse():
        pass

Existe-t-il un moyen de créer un alias pour ne pas avoir à vérifier quelle est la valeur de l'argument non positionnel foo? Quelque chose comme

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

    def _sse():
        pass
0
b-fg 19 mars 2019 à 12:30

2 réponses

Meilleure réponse

Utilisation de @KlausD. suggestion et l'inclusion de alias dans la méthode __init__ fait l'affaire pour moi.

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
0
b-fg 20 mars 2019 à 07:51

Réponse technique: vous pouvez le faire en définissant la fonction cible avant l'initialiseur, en référençant cette fonction comme argument par défaut (les fonctions Python sont aussi des objets), et en appelant manuellement le protocole descripteur sur la fonction cible:

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

Notez simplement qu'avec cette solution, si vous voulez passer une autre fonction, cette fonction doit prendre self comme premier argument:

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

Maintenant, à partir d'un POV de lisibilité, c'est à peine une amélioration à mon humble avis ...

EDIT: comme le mentionne Aran-Fey, cela ne répond pas exactement à la question, donc pour une version plus "littérale" (et cela ne nécessite pas de définitions spéciales, etc.):

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)

Mais cela n'améliore toujours pas la lisibilité ...

1
bruno desthuilliers 19 mars 2019 à 10:05