문제

자주 보입니다 __init__ 방법은 이것과 유사합니다.

def __init__(self, ivar1, ivar2, ivar3):
    self.ivar1 = ivar1
    self.ivar2 = ivar2
    self.ivar3 = ivar3

인수를 목록으로 바꿀 수있는 곳이 있습니까 (의지하지 않고 *args 또는 **kwargs) 그런 다음 사용합니다 setattr 매개 변수 이름과 인수가 통과 된 인스턴스 변수를 설정하려면? 그리고 아마도 목록을 자울 수도 있습니다. 예를 들어 적어도 슬라이스해야 할 것입니다. [1:] 당신은 원하지 않기 때문에 self.self.

(실제로 이름과 가치를 유지하려면 사전이어야 할 것 같아요)

이와 같이:

def __init__(self, ivar1, ivar2, ivar3, optional=False):
    for k, v in makedict(self.__class__.__init__.__args__): # made up __args__
        setattr(self, k, v)

감사!

미지의 답변에 응답하면서, 나는 이것이 효과가 있음을 알았습니다.

Class A(object):
    def __init__(self, length, width, x):
        self.__dict__.update(dict([(k, v) for k, v in locals().iteritems() if k != 'self']))

또는

Class A(object):
    def __init__(self, length, width, x):
        self.__dict__.update(locals())
        del self.__dict__['self']

나쁘지 않아..

도움이 되었습니까?

해결책

당신은 간다. 예, 이것은 못생긴 사악한 해킹입니다. 예 객체에는 __dict__ 변수가 필요합니다. 하지만 이봐, 그 깔끔한 작은 하나의 라이너!

def __init__(self):
    self.__dict__.update(locals())

생성자는 모든 유형의 인수를 취할 수 있습니다.

class test(object):
    def __init__(self, a, b, foo, bar=5)...

a = test(1,2,3)
dir(a)

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'foo', 'bar', 'self']

또한 자아가 포함되지만 쉽게 삭제하거나 자기를 무시하는 자신의 업데이트 기능을 만들 수 있습니다.

다른 팁

expect.getargspec을 사용하여 데코레이터로 캡슐화 할 수 있습니다. 선택 사항 및 키워드 인수 조회는 약간 까다 롭지 만 그렇게해야합니다.

def inits_args(func):
    """Initializes object attributes by the initializer signature"""
    argspec = inspect.getargspec(func)
    argnames = argspec.args[1:]
    defaults = dict(zip(argnames[-len(argspec.defaults):], argspec.defaults))
    @functools.wraps(func)
    def __init__(self, *args, **kwargs):
        args_it = iter(args)
        for key in argnames:
            if key in kwargs:
                value = kwargs[key]
            else:
                try:
                    value = args_it.next()
                except StopIteration:
                    value = defaults[key]
            setattr(self, key, value)
        func(self, *args, **kwargs)
    return __init__

그런 다음 다음과 같이 사용할 수 있습니다.

class Foo(object):
    @inits_args
    def __init__(self, spam, eggs=4, ham=5):
        print "Foo(%r, %r, %r)" % (self.spam, self.eggs, self.ham)

기능 서명에 개별적으로 지정된 경우 인수를 목록으로 얻는 좋은 방법은 없습니다. 당신은 아마도 검사 나 프레임 해킹으로 무언가를 할 수 있지만, 당신이했던 것처럼 철자를 철자하는 것보다 추악 할 것입니다.

노력하다 검사 .getArgSpec:

In [31]: inspect.getargspec(C.__init__)

Out[31]: ArgSpec(args=['self', 'ivar1', 'ivar2', 'ivar3', 'optional'],

                 varargs=None, keywords=None, defaults=(False,))

컬렉션 모듈의 새로운 지명 (Python 2.6의 새로운)이 귀하에게 효과적 일 수 있는지 확인하십시오.

인수의 내성을 사용하여 수행 할 수 있지만 코드는 대체하려는 코드보다 길어집니다. 특히 KW를 처리하는 경우해야합니다.

이 짧은 코드는 대부분의 경우 작동합니다 (미지의 예에서 개선) :

>>> class Foo:
...   def __init__(self, labamba, **kw):
...       params = locals().copy()
...       del params['self']
...       if 'kw' in params:
...           params.update(params['kw'])
...           del params['kw']
...       self.__dict__.update(params)

그러나 그것은 추악한 해킹으로, 게으름을 제외하고는 특별한 이유없이 코드를 읽기 쉽게 만들 수 있으므로 그렇게하지 마십시오. 또한 얼마나 자주 당신을합니까? 진짜 5-6 이상의 init 매개 변수가있는 클래스가 있습니까?

나는 그 형태가 너무 길고 너무 길지 않고 복사 가능하고 하위 클래식을 좋아합니다.

class DynamicInitClass(object):
      __init_defargs=('x',)
      def __init__(self,*args,**attrs):
        for idx,val in enumerate(args): attrs[self.__init_defargs[idx]]=val
        for key,val in attrs.iteritems(): setattr(self,key,val)

특별 수업에서 파생하는 것은 어떻습니까? 나는 그것이 생각합니다 더 명시적이고 유연합니다 이 방법:

class InitMe:
    def __init__(self, data):
        if 'self' in data:
             data = data.copy()
             del data['self']
        self.__dict__.update(data)


class MyClassA(InitMe):
    def __init__(self, ivar1, ivar2, ivar3 = 'default value'):
        super().__init__(locals())


class MyClassB(InitMe):
    def __init__(self, foo):
        super().__init__({'xxx': foo, 'yyy': foo, 'zzz': None})
# or    super().__init__(dict(xxx=foo, yyy=foo, zzz=None))

class MyClassC(InitMe):
    def __init__(self, foo, **keywords):
        super().__init__(keywords)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top