2016-11-11 2 views
9

Il est parfois commun en Python pour voir le code __init__ comme ceci:Existe-t-il un raccourci Python pour un __init__ qui définit simplement les propriétés?

class SomeClass(object): 
    def __init__(self, a, b, c, d, e, f, g): 
     self.a = a 
     self.b = b 
     self.c = c 
     self.d = d 
     self.e = e 
     self.f = f 
     self.g = g 

surtout si la classe en question est purement une structure de données sans comportement. Y a-t-il un raccourci (Python 2.7) pour ça ou un moyen d'en faire un?

+6

Si votre classe n'a pas de comportement, vous pouvez utiliser un [** 'namedtuple' **] (https://docs.python.org/2 /library/collections.html#collections.namedtuple) à la place. –

+0

@PeterWood Oui, cela fonctionne bien pour mes fins. Vous pouvez le poster comme une réponse pour que je puisse l'accepter. – naiveai

+0

Vous êtes en mesure de poster une réponse à votre propre question (c :. Faites-le bien, il va être upvoted, et vous pouvez même l'accepter.Je n'ai pas toujours le temps d'écrire de bonnes réponses, mais profiter doucement poussant Les gens dans la bonne direction –

Répondre

8

Vous pourriez trouver la bibliothèque attrs utile. Voici un exemple de la overview page des docs:

>>> import attr 
>>> @attr.s 
... class C(object): 
...  x = attr.ib(default=42) 
...  y = attr.ib(default=attr.Factory(list)) 
... 
...  def hard_math(self, z): 
...   return self.x * self.y * z 
>>> i = C(x=1, y=2) 
>>> i 
C(x=1, y=2) 
+0

Je suis content qu'ils aient au moins les "alias business sérieux" pour s() et ib(). – grawity

11

Vous pouvez utiliser Alex Martelli Bunch recipe:

class Bunch(object): 
    """ 
    foo=Bunch(a=1,b=2) 
    """ 
    def __init__(self, **kwds): 
     self.__dict__.update(kwds) 
+1

Le problème avec ceci est qu'il n'y a aucun moyen de contrôler quelles propriétés sont là, mais c'est une bonne solution générale – naiveai

+4

Comme le suggère Peter Wood : //stackoverflow.com/questions/40545922/is-there-a-python-shortcut-for-an-init-that-simply-sets-properties/40545993? noredirect = 1 # comment68330675_40545922), si vous voulez un nombre fixe des attributs nommés, utilisez plutôt un [namedtuple] (https://docs.python.org/2/library/collections.html#collections.namedtuple) – unutbu

+1

Cela ne prend pas en charge les arguments positionnels –

2

Vous pouvez faire une classe avec une méthode __new__ qui copie les propriétés de la classe à d'objet, puis hériter de cela.

http://www.oreilly.com/programming/free/how-to-make-mistakes-in-python.csp a un exemple de pourquoi ce que je viens de dire est une idée terrible qui devrait être évitée.

(version courte: il ne fonctionne pas bien avec des objets mutables, et les contournements pour faire face à qui ne valent pas l'effort.)

4

Bien sûr.

Class SomeClass(object): 
    def __init__(self, **args): 
     for(k, v) in args.items(): 
      setattr(self, k, v) 

Et v = SomeClass(a=1, b=2, c=3, d=4)

Bug il serait votre code difficile à comprendre.

Bonne chance.

+1

Cela empêche de définir facilement les valeurs par défaut n'est-ce pas? ave les coder en dur dans la fonction comme 'self.some_value = 123', ce qui va à l'encontre de l'objectif d'avoir une fonction constructeur courte et concise. –