2008-09-20 11 views
78

파이썬에 모든 클래스의 인스턴스 변수의 배열을 가져 오는 기본 제공 메소드가 있습니까? 이 코드가있는 경우 예를 들어, :파이썬에서 인스턴스 변수를 얻는 방법?

>>> mystery_method(hi) 
["ii", "kk"] 

편집 : 나는 원래 잘못 클래스 변수를 요청했다

class hi: 
    def __init__(self): 
    self.ii = "foo" 
    self.kk = "bar" 

날이 할 수있는 방법이 있습니까.

+0

귀하의 예는 "인스턴스 변수"를 보여줍니다. 클래스 변수는 또 다른 것입니다. –

답변

93

모든 개체에는 __dict__ 변수가 있으며 모든 변수와 그 값이 포함되어 있습니다.

은 적어도 클래스를 인스턴스화하지 않고,이

>>> hi_obj = hi() 
>>> hi_obj.__dict__.keys() 
+7

FWIW, inspect 모듈은 모든 인스턴스에있는 것은 아니지만 __dict__에 의존하는 것보다 더 안정적인 방법을 제공합니다. –

+1

어떤 종류의 인스턴스에 __dict__이 없습니까? 나는 결코 그것을 만난 적이 없다. –

+3

int와 같은 특정 기본 제공 유형. "x = 5"라고 말한 다음 "x .__ dict__"이라고 말하면 AttributeError가 나타날 것입니다. –

13

당신은 일반적으로 얻을 수없는 인스턴스가 단지 클래스를 주어진 속성을보십시오. 인스턴스가 주어지면 인스턴스 속성을 얻을 수 있지만, 클래스가 주어지면 클래스 속성을 가져올 수 있습니다. 'inspect'모듈을보십시오. 인스턴스는 실제로 속성을 가질 수 있기 때문에 인스턴스 속성의 목록을 얻을 수 없습니다. 예를 들어서와 같이 인스턴스를 만드는 일반적인 방법은 __init__ 메소드에서 인스턴스에 할당하는 것입니다.

클래스에서 인스턴스를 가질 수있는 고정 된 속성 목록 인 슬롯을 사용하는 경우는 예외입니다. 슬롯은 http://www.python.org/2.2.3/descrintro.html에 설명되어 있지만 슬롯이있는 여러 가지 함정이 있습니다. 그것들은 메모리 레이아웃에 영향을 미치므로 다중 상속은 문제가 될 수 있으며 상속은 일반적으로 슬롯을 고려해야합니다.

+0

downvoting "인스턴스 속성 목록을 가져올 수 없습니다"는 간단히 잘못된 것입니다. vars()와 __dict__는 모두이를 정확하게 나타냅니다. –

+2

나는 그가 "가능한 모든 인스턴스 속성의 목록을 가져올 수 없다"는 것을 의미한다고 가정합니다. 예를 들어, 게으른 생성 및 @property 데코레이터를 사용하여 처음 인스턴스 변수를 추가 할 때 자주 사용합니다. __dict__를 사용하면이 변수가 존재했으나 사전에 알려지지 않은 변수에 대해 알려줍니다. –

+4

나는 downvote하지 않았고, 내가 실제로 말한 것을 주목해라. 질문에 수반되는 코드가 시도하는 클래스 * 만 주어지는 인스턴스 속성 목록을 얻을 수 없다. –

9

객체와 특정 변수가있는 경우 또한 테스트 할 수 있습니다

>>> hi_obj = hi() 
>>> hasattr(hi_obj, "some attribute") 
4

귀하의 예는 "인스턴스 변수"정말 클래스 변수를 보여줍니다.

구성원 변수 및 포함 모듈과 같은 다른 클래스 멤버와 함께 클래스 변수에 대해서는 hi_obj.__class__.__dict__.items()을 참조하십시오.

class Hi(object): 
    class_var = (23, 'skidoo') # class variable 
    def __init__(self): 
     self.ii = "foo" # instance variable 
     self.jj = "bar" 

클래스 변수는 클래스의 모든 인스턴스에서 공유됩니다. 영업 질문에 직접적으로 대답, 아주 달콤한이 있지만

class Foo(object): 
    def __init__(self): 
     self.a = 1 
     self.b = 2 

vars(Foo()) #==> {'a': 1, 'b': 2} 
vars(Foo()).keys() #==> ['a', 'b'] 
73

사용 바르가(), 그것은 본질적으로 __dict__

+6

+1 이중 밑줄이있는 속성은 파이썬 구문에서 "private"로되어 있기 때문에 개인적으로이 구문이 __dict__를 사용하는 것보다 깔끔하다고 생각합니다. –

+2

@Martin :'__method'는 private입니다.'__method__'는 특별한 방법입니다. 특수 메서드가 메서드가 아니라 개체의 기능을 정의한다고 말하고 싶습니다. – u0b34a0f6ae

+2

'__method__'은 꽤 못 생겼고 절대적으로 필요한 경우를 제외하고는 사람들이 사용하지 못하도록하는 방식으로 명명 된 것 같습니다. 이 경우 대체 vars()가 있습니다. –

6

가 otherwords에서

>>> print vars.__doc__ 
vars([object]) -> dictionary 

Without arguments, equivalent to locals(). 
With an argument, equivalent to object.__dict__. 

제안

5

를 래핑 함수에서 어떤 변수가 범위 내에 있는지 알아내는 방법. 다음 코드를 살펴보십시오 :

>>> def f(x, y): 
    z = x**2 + y**2 
    sqrt_z = z**.5 
    return sqrt_z 

>>> f.func_code.co_varnames 
('x', 'y', 'z', 'sqrt_z') 
>>> 

func_code 속성에는 모든 종류의 흥미로운 것들이 있습니다. 그것은 당신이 멋진 것들을 할 수 있습니다.영업 이익은 게시 된 예를 들어 작동합니다

def exec_command(self, cmd, msg, sig): 

    def message(msg): 
     a = self.link.process(self.link.recieved_message(msg)) 
     self.exec_command(*a) 

    def error(msg): 
     self.printer.printInfo(msg) 

    def set_usrlist(msg): 
     self.client.connected_users = msg 

    def chatmessage(msg): 
     self.printer.printInfo(msg) 

    if not locals().has_key(cmd): return 
    cmd = locals()[cmd] 

    try: 
     if 'sig' in cmd.func_code.co_varnames and \ 
         'msg' in cmd.func_code.co_varnames: 
      cmd(msg, sig) 
     elif 'msg' in cmd.func_code.co_varnames: 
      cmd(msg) 
     else: 
      cmd() 
    except Exception, e: 
     print '\n-----------ERROR-----------' 
     print 'error: ', e 
     print 'Error proccessing: ', cmd.__name__ 
     print 'Message: ', msg 
     print 'Sig: ', sig 
     print '-----------ERROR-----------\n' 
11

모두 바르() 및 DICT 방법,하지만 그들은 "느슨하게"정의 된 객체와 같은 작동하지 않습니다 : 여기이 사용하고있는 방법의 예입니다 :

class foo: 
    a = 'foo' 
    b = 'bar' 

이 아닌 모든 호출 특성을 인쇄하려면, 다음과 같은 기능을 사용할 수 있습니다 :

def printVars(object): 
    for i in [v for v in dir(object) if not callable(getattr(object,v))]: 
     print '\n%s:' % i 
     exec('print object.%s\n\n') % i 
+4

'exec ('인쇄 객체. % s \ n \ n') % i'는'print getattr (object, i)'로 쓰여 져야합니다. – user102008

관련 문제