获取类的属性

Moh*_*mis 79 python attributes class python-2.7

我想得到一个类的属性,比如说:

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

  def myfunc(self):
    return self.a
Run Code Online (Sandbox Code Playgroud)

使用MyClass.__dict__给我一个属性和功能的列表,甚至像__module__和的功能__doc__.虽然MyClass().__dict__我给了一个空的dict,除非我明确设置了该实例的属性值.

我只想要属性,在上面的例子中,那些将是:ab

Mat*_*ngo 98

尝试检查模块.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')]
Run Code Online (Sandbox Code Playgroud)

现在,特殊的方法和属性让我神经紧张 - 可以通过多种方式处理,最简单的方法就是根据名称进行过滤.

>>> 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')]
Run Code Online (Sandbox Code Playgroud)

...而且更复杂的可以包括特殊属性名称检查甚至元类;)

  • 注意-不会包含属性like_this!它还将避免您可能故意创建的“私有”属性。 (2认同)

Dou*_*oug 32

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

properties = props(MyClass)
Run Code Online (Sandbox Code Playgroud)

  • 这将包括方法名称 (6认同)
  • 更不清楚要检查:`如果不是i.startswith('_')`而不是`if i [:1]!='_'`? (6认同)
  • 注意:如果我们谈论子类(继承),则`.__ dict __。keys()`将不包含父类的属性。 (2认同)

Ben*_*Ben 19

myfunc 一个属性MyClass.这就是你跑步时的表现:

myinstance = MyClass()
myinstance.myfunc()
Run Code Online (Sandbox Code Playgroud)

它在myinstancenamed myfunc上查找属性,找不到一个属性,看到它myinstance是一个实例MyClass并在那里查找它.

所以完整的属性列表MyClass是:

>>> dir(MyClass)
['__doc__', '__module__', 'a', 'b', 'myfunc']
Run Code Online (Sandbox Code Playgroud)

(请注意,我正在使用dir作为列出类成员的快速简便方法:它应该只以探索方式使用,而不是在生产代码中使用)

如果你只想要特定属性,则需要使用一些标准来过滤此列表,因为__doc__,__module__myfunc没有特殊的以任何方式,他们在完全相同的方式属性,这些属性ab是.

我从来没有使用过Matt和Borealid提到的检查模块,但是从一个简短的链接看起来它有测试可以帮助你做到这一点,但你需要编写自己的谓词函数,因为它似乎你想要的大致是没有通过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']
Run Code Online (Sandbox Code Playgroud)

  • 一个人不能依赖于`dir()`:"_因为dir()主要是为了方便在交互式提示下使用而提供的,**它试图提供一组有趣的名称,而不是试图提供严格或一致的定义一组名称**,**其详细行为可能会在各版本中发生变化**._"(参见[dir()`文档](http://docs.python.org/library/functions.html#dir )). (5认同)

oli*_*bre 7

仅获取实例属性很容易。
但是在没有函数的情况下获取类属性也比较棘手。

仅实例属性

如果您只需要列出实例属性,请使用
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
Run Code Online (Sandbox Code Playgroud)

实例和类属性

要获得没有功能的类属性,诀窍是使用callable()

静态方法不总是callable

因此,不要使用callable(value)use
callablegetattrMyClass, 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 MyClass.__dict__.keys():
       if attribute[:2] != '__':
         value = getattr(MyClass, attribute)
         if not callable(value):
           print(attribute, '=', value)

v = MyClass(4,2)
v.print_class_attributes()
v.print_instance_attributes()
Run Code Online (Sandbox Code Playgroud)

注意:       在这个愚蠢而简单的示例中,print_class_attributes()应该(但不应该)。@staticmethod

结果

$ python2 ./print_attributes.py
[class attributes]
a = 12
b = 34
[instance attributes]
c = 4
d = 2
Run Code Online (Sandbox Code Playgroud)

结果相同

$ python3 ./print_attributes.py
[class attributes]
b = 34
a = 12
[instance attributes]
c = 4
d = 2
Run Code Online (Sandbox Code Playgroud)


Bor*_*lid 6

MyClass().__class__.__dict__

然而,"权利"是通过检查模块来做到这一点.

  • `MyClass().__ class __.__ dict__` ==`MyClass .__ dict__` (4认同)
  • @ yak的评论并不完全正确.请参阅以下有关类和实例属性之间差异的信息.请参阅http://stackoverflow.com/questions/35805/why-is-my-instance-variable-not-in-dict. (4认同)
  • @sholsapp 实际上@yak 是对的。您提供的链接显示 `MyClass().__class__.__dict__ != MyClass().__dict__`,但 yak 不包括右侧的括号,在这种情况下她/他是正确的 (2认同)