Le parfait, mais impossible, scénario serait:avec des mots-clés à partir des attributs des instances
class example(object):
def __init__(self,x,y):
self.x = x
self.y = y
def foo(self, x = self.x, y = self.y):
return x + y
Il ne fonctionne pas parce que auto n'est pas défini. J'ai fait beaucoup de recherches, j'ai regardé des décorateurs, des descripteurs, des métaclasses, presque tout. La solution peut être la plus évidente et la plus connue de tous, mais je ne l'ai pas trouvée. Je pouvais gérer deux solutions de contournement, comme suit:
def prep(argslist, argsprovided, attributes):
argsout = []
for name in argslist:
if name in argsprovided:
argsout.append(argsprovided[name])
else:
argsout.append(getattr(attributes,name))
return argsout
class example(object):
# I can create a default instance or a custom one
def __init__(self,x = 1,y = 1,z = 1,w = 1):
self.x = x
self.y = y
self.z = z
self.w = w
# I can wrap a function to use the self argument
def wrapper(self):
def foo(x = self.x, y = self.y, z = self.z, w = self.w):
return x + y + z + w
return foo
# I can wrap 'joo' alongside with foo, and make 'wrapper' return a list
def joo(self, **kwargs):
[x,y,z,w] = prep(['x','y','z','w'],kwargs,self)
return x + y + z + 2*w
# I can use my custom 'prep' function to to the job
def foo(self, **kwargs):
[x,y,z,w] = prep(['x','y','z','w'],kwargs,self)
return x + y + z + w
# Creates a default instance and a custom one
c = example()
d = example(2,2,2,2)
# I can use 'foo' with the instance's default values with both wrapping and 'prepping'
print(c.wrapper()())
print(d.wrapper()())
print(c.foo())
print(d.foo())
# I can use 'foo' with a mix of default values and provided values with both wrapping and 'prepping'
print(c.wrapper()(1,2,3))
print(d.wrapper()(1,2,3))
print(c.foo(y = 3,z = 4,w = 5))
print(d.foo(y = 3,z = 4,w = 5))
Le code imprime:
4
8
4
8
7
8
13
14
J'ai une grande classe avec beaucoup de fonctions, chacun a besoin le comportement de « foo ». Ma solution de préparation prend trop de temps. Après avoir profilé le code, j'ai pensé qu'il passait 12 secondes à l'intérieur de la préparation seulement. Qu'est-ce qu'une façon intelligente et moins longue de faire cela? Je suis complètement perdu.
C'est en effet plus rapide! C'est une bonne option, mais certaines de mes fonctions prennent plus de 10 arguments, donc ce n'est pas ce practicle. La méthode wrapper est juste un peu plus lente. Le meilleur moyen est de définir k = c.wrapper(), puis d'utiliser k(). – RFiischer