[python] 클래스의 속성 얻기

클래스의 속성을 얻고 싶습니다.

class MyClass():
  a = "12"
  b = "34"

  def myfunc(self):
    return self.a

를 사용 MyClass.__dict__하면 속성 및 함수 목록과 __module__및 같은 함수도 제공 __doc__됩니다. 하지만 MyClass().__dict__나에게 빈 딕셔너리를 제공 I 명시 적으로 해당 인스턴스의 속성 값을 설정하지 않는 한.

위의 예에서 속성은 다음 a과 같습니다.b



답변

검사 모듈을 사용해보십시오 . getmembers다양한 테스트가 도움이 될 것입니다.

편집하다:

예를 들면

class MyClass(object):
    a = '12'
    b = '34'
    def myfunc(self):
        return self.a

>>> import inspect
>>> inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
[('__class__', type),
 ('__dict__',
  <dictproxy {'__dict__': <attribute '__dict__' of 'MyClass' objects>,
   '__doc__': None,
   '__module__': '__main__',
   '__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
   'a': '34',
   'b': '12',
   'myfunc': <function __main__.myfunc>}>),
 ('__doc__', None),
 ('__module__', '__main__'),
 ('__weakref__', <attribute '__weakref__' of 'MyClass' objects>),
 ('a', '34'),
 ('b', '12')]

이제 특별한 방법과 속성이 제 신경을 씁니다. 여러 방법으로 다룰 수 있습니다. 가장 쉬운 방법은 이름을 기준으로 필터링하는 것입니다.

>>> attributes = inspect.getmembers(MyClass, lambda a:not(inspect.isroutine(a)))
>>> [a for a in attributes if not(a[0].startswith('__') and a[0].endswith('__'))]
[('a', '34'), ('b', '12')]

… 더 복잡한 것은 특수 속성 이름 검사 또는 메타 클래스를 포함 할 수 있습니다.)


답변

def props(cls):
  return [i for i in cls.__dict__.keys() if i[:1] != '_']

properties = props(MyClass)


답변

myfunc 이다 의 속성 MyClass. 다음과 같이 실행할 때 발견됩니다.

myinstance = MyClass()
myinstance.myfunc()

myinstance이름이 지정된 속성을 myfunc찾고, 하나를 찾지 못하고 myinstance, 인스턴스 인 것을보고 MyClass거기에서 찾습니다.

따라서에 대한 전체 속성 목록 MyClass은 다음과 같습니다.

>>> dir(MyClass)
['__doc__', '__module__', 'a', 'b', 'myfunc']

(저는 클래스 멤버를 나열하는 빠르고 쉬운 방법으로 dir을 사용하고 있습니다. 프로덕션 코드가 아닌 탐색 적 방식으로 만 사용해야합니다.)

당신은 단지 특정 속성을 원하는 경우에 때문에, 당신은 몇 가지 기준을 사용하여이 목록을 필터링해야합니다 __doc__, __module__그리고 myfunc어떤 방법으로 특별하지 않은 사람들은 정확히 같은 방식으로,있는 거 특성을 a하고 b있습니다.

Matt와 Borealid가 참조하는 inspect 모듈을 사용한 적이 없지만 간단한 링크를 보면이 작업을 수행하는 데 도움이되는 테스트가있는 것처럼 보이지만 원하는대로 보이기 때문에 자체 조건 자 함수를 작성해야합니다. 대략 속성입니다 하지 않는 패스 isroutine테스트를하고 시작하고 두 개의 밑줄로 끝나지 않습니다.

또한 참고 : class MyClass():Python 2.7에서 사용하면 매우 오래된 구식 클래스를 사용하게됩니다. 매우 오래된 라이브러리와의 호환성을 위해 의도적으로 그렇게하지 않는 한, 대신 클래스를 class MyClass(object):. Python 3에는 “이전 스타일”클래스가 없으며이 동작이 기본값입니다. 그러나 newstyle 클래스를 사용하면 훨씬 더 자동으로 정의 된 속성을 얻을 수 있습니다 .

>>> class MyClass(object):
        a = "12"
        b = "34"
        def myfunc(self):
            return self.a
>>> dir(MyClass)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'a', 'b', 'myfunc']


답변

인스턴스 속성 만 가져 오는 것은 쉽습니다.
그러나 함수없이 클래스 속성 을 가져 오는 것은 좀 더 까다 롭습니다.

인스턴스 속성 만

인스턴스 속성 만 나열해야하는 경우
for attribute, value in my_instance. __dict__.items()

>>> from __future__ import (absolute_import, division, print_function)
>>> class MyClass(object):
...   def __init__(self):
...     self.a = 2
...     self.b = 3
...   def print_instance_attributes(self):
...     for attribute, value in self.__dict__.items():
...       print(attribute, '=', value)
...
>>> my_instance = MyClass()
>>> my_instance.print_instance_attributes()
a = 2
b = 3
>>> for attribute, value in my_instance.__dict__.items():
...   print(attribute, '=', value)
...
a = 2
b = 3

인스턴스 및 클래스 속성

함수없이 클래스 속성 도 얻으려면 callable().

그러나 정적 메서드항상 그런 것은 아닙니다callable !

따라서 사용 callable(value)하는 대신
callable( getattr(MyClass, attribute))

from __future__ import (absolute_import, division, print_function)

class MyClass(object):
   a = "12"
   b = "34"               # class attributes

   def __init__(self, c, d):
     self.c = c
     self.d = d           # instance attributes

   @staticmethod
   def mystatic():        # static method
       return MyClass.b

   def myfunc(self):      # non-static method
     return self.a

   def print_instance_attributes(self):
     print('[instance attributes]')
     for attribute, value in self.__dict__.items():
        print(attribute, '=', value)

   def print_class_attributes(self):
     print('[class attributes]')
     for attribute in self.__dict__.keys():
       if attribute[:2] != '__':
         value = getattr(self, attribute)
         if not callable(value):
           print(attribute, '=', value)

v = MyClass(4,2)
v.print_class_attributes()
v.print_instance_attributes()

참고 :
      이 어리 석고 간단한 예제 에는 print_class_attributes()있어야합니다 .@staticmethod

결과

$ python2 ./print_attributes.py
[class attributes]
a = 12
b = 34
[instance attributes]
c = 4
d = 2

동일한 결과

$ python3 ./print_attributes.py
[class attributes]
b = 34
a = 12
[instance attributes]
c = 4
d = 2


답변

MyClass().__class__.__dict__

그러나 “올바른”방법은 inspect 모듈을 사용하는 것 입니다.


답변

import re

class MyClass:
    a = "12"
    b = "34"

    def myfunc(self):
        return self.a

attributes = [a for a, v in MyClass.__dict__.items()
              if not re.match('<function.*?>', str(v))
              and not (a.startswith('__') and a.endswith('__'))]

다음과 같은 MyClass 인스턴스의 경우

mc = MyClass()

목록 이해력 type(mc)대신 사용 MyClass하십시오. 하나의 동적에 속성 추가하는 경우, mc등을 mc.c = "42"사용하는 경우, 속성은 표시되지 않습니다type(mc) 이 전략에. 원래 클래스의 속성 만 제공합니다.

클래스 인스턴스에 대한 완전한 사전을 얻으려면 type(mc).__dict__및 의 사전을 결합해야합니다 mc.__dict__.

mc = MyClass()
mc.c = "42"

# Python 3.5
combined_dict = {**type(mc).__dict__, **mc.__dict__}

# Or Python < 3.5
def dict_union(d1, d2):
    z = d1.copy()
    z.update(d2)
    return z

combined_dict = dict_union(type(mc).__dict__, mc.__dict__)

attributes = [a for a, v in combined_dict.items()
              if not re.match('<function.*?>', str(v))
              and not (a.startswith('__') and a.endswith('__'))]


답변

비슷한 것이 지금까지 만들어 졌는지 여부는 모르겠지만 vars ()를 사용하여 멋진 속성 검색 기능을 만들었습니다. vars ()는 전달하는 클래스의 속성 사전을 만듭니다.

class Player():
    def __init__(self):
        self.name = 'Bob'
        self.age = 36
        self.gender = 'Male'

s = vars(Player())
#From this point if you want to print all the attributes, just do print(s)

#If the class has a lot of attributes and you want to be able to pick 1 to see
#run this function
def play():
    ask = input("What Attribute?>: ")
    for key, value in s.items():
        if key == ask:
            print("self.{} = {}".format(key, value))
            break
    else:
        print("Couldn't find an attribute for self.{}".format(ask))

저는 Python으로 꽤 방대한 텍스트 어드벤처를 개발 중이며 지금까지 내 Player 클래스에는 100 개 이상의 속성이 있습니다. 이 기능을 사용하여 확인해야하는 특정 속성을 검색합니다.