2011-02-19 24 views
7

__init__ yönteminin argümanlarını otomatik olarak self (bazılarının) argümanlarına bağlamanın bir yolu var mı? yerineOtomatik ciltleme için python dekoratör __init__ arguments

class Person: 
    @lazy_init 
    def __init__(self, name, age, address): 
     ... 

...: insanlar zaten bu gibi durumlarda kullandıkları benzer bir şey olmadığını merak

class Person: 
    def __init__(self, name, age, address): 
     self.name = name 
     self.age = age 
     self.address = address 
     ... 

ben gibi bir şey yani. Ya da ilk etapta böyle yapmamamın bir sebebi var mı? Eğer özelliklerine haritasına nitelikler dışında bir şey olması başladıktan sonra, gerçi zorluklarla karşılaşmaya gidiyoruz

def lazy_init(init): 
    import inspect 
    arg_names = inspect.getargspec(init)[0] 

    def new_init(self, *args): 
     for name, value in zip(arg_names[1:], args): 
      setattr(self, name, value) 
     init(self, *args) 

    return new_init 

class Person: 
    @lazy_init 
    def __init__(self, name, age): 
     pass 

p = Person("Derp", 13) 
print p.name, p.age 

:

cevap

4

O burada biraz naif uygulanması kesinlikle mümkün oluyor. En az bir yolun, özellik olarak başlatılması gereken satırları belirtmek için bir yoluna ihtiyacınız olacak ... bu noktada, değerinden daha fazla güçlük çekecek.

+0

teşekkürler. '__init__' yönteminin karmaşık olması durumunda buna değmeyeceğinin farkındayım, ancak basit olanlar o kadar yaygın ki, bunun gibi bir şeye sahip olmanın güzel olacağını düşünüyorum. –

0

bkz:

def lazy_init(*param_names): 
    def ret(old_init): 
    def __init__(self, *args, **kwargs): 
     if len(args) > len(param_names): 
     raise TypeError("Too many arguments") 
     for k in kwargs: 
     if k not in param_names: 
      raise TypeError("Arg %r unexpected" % k) 
     for par, arg in zip(param_names, args): 
     setattr(self, par, arg) 
     for par, arg in kwargs.items(): 
     setattr(self, par, arg) 
     old_init(*args, **kwargs) 
    return __init__ 
    # 
    return ret 


class Q(object): 
    @lazy_init("a", "b") 
    def __init__(self, *args, **kwargs): 
    print "Original init" 

>>> q = Q(1, 2) 
Original init 
>>> q.a, q.b 
(1, 2) 

çok __str__ kapsayacak bir sınıf dekoratör oluşturmayı düşünün.

0

initify.py bana tarafından oluşturuldu :) tam olarak ne beklediğinizi yapar.

class Animal: 
    @init_args(exclude=["name"]) 
    def __init__(self, name): 
     pass 

veya varsayılan değerlerle

: miras hariç

class Animal: 
    @init_args 
    def __init__(self, name="Default name"): 
     pass 

hatta:

class Dog(Animal): 
    @init_args(exclude=["name"]) 
    def __init__(self, species): 
     pass 

https://github.com/prankymat/initify.py

İlgili konular