Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 获取不带方法和内置项的类的类和对象属性_Python_Introspection - Fatal编程技术网

Python 获取不带方法和内置项的类的类和对象属性

Python 获取不带方法和内置项的类的类和对象属性,python,introspection,Python,Introspection,假设我有这门课: class MyClass(object): my_attrib = 'foo' my_other_attrib = 'bar' def mymethod(): pass 现在,我如何只获取类MyClass的属性,而不获取方法和内置项,如\uu dict\uu等等 当应用到上面的类时,我想得到一个类似于{'my_attrib':'foo','my_other_attrib':'bar'}。\u dict\u提供了所有这些,但是你可以使用C扩展来获得你想要

假设我有这门课:

class MyClass(object):
  my_attrib = 'foo'
  my_other_attrib = 'bar'

  def mymethod():
    pass
现在,我如何只获取类MyClass的属性,而不获取方法和内置项,如
\uu dict\uu
等等


当应用到上面的类时,我想得到一个类似于
{'my_attrib':'foo','my_other_attrib':'bar'}

\u dict\u
提供了所有这些,但是你可以使用
C
扩展来获得你想要的。不知道你为什么要这么做


您可以使用
类型
()来区分
\uuuuu dict\uuuuu
的成员,这将使您更接近:

import inspect

class MyClass(object):
  my_attrib = 'foo'
  my_other_attrib = 'bar'

  def mymethod():
    pass

for name, value in inspect.getmembers(MyClass):
    if not inspect.ismethod(value) and not name.startswith('__'):
        print name
这将产生:

my_attrib
my_other_attrib


注意-可能有更好/更正式的方法来实现这一点,但这应该为您指明了正确的方向。

您可以从
\uuuu dict\uuuu
中筛选出不需要的所有内容:

def getAttributes(clazz):
    return {name: attr for name, attr in clazz.__dict__.items()
            if not name.startswith("__") 
            and not callable(attr)
            and not type(attr) is staticmethod}
编辑:对于类属性和描述符的行为略有不同的替代方法:

def getAttributes2(clazz):
    attrs = {}
    for name in vars(clazz):
        if name.startswith("__"):
            continue
        attr = getattr(clazz, name)
        if callable(attr):
            continue
        attrs[name] = attr
    return attrs

(实际上,这应该与第一个版本几乎没有什么不同。)

您可以使用内置的
dir()
获取所有内容,然后进行筛选。您将不需要
检查
模块

def get_attrs_without_methods(klass):
    attrs = dir(klass)
    d = {}
    for x in attrs:
        if x.startswith('__'): continue
        value = getattr(self,x)
        if not callable(value):
            d[x] = value
    
    return d
有时,您可能希望仅获取类变量,而不是类变量和实例变量。 您可以通过依赖
\uuu dict\uu
筛选出实例变量。或者,您可以使用
\uuuuu class\uuuu
获取属性并过滤掉方法<代码>\uuuu类\uuuu
不返回实例变量

#after collecting your attributes using the above example...
for attr, value in vars(obj).items():
    d.pop(attr) #remove instance variables from the dict

#both vars(obj).items() and obj.__dict__.items() return similar iterable.

请注意,如果对象实现重写
\uuuuu dict\uuuuuu
并返回None,
vars(obj)
obj.\uuuuu dict\uuuuuuuuuuj.items()
将不会返回字典。

为什么我们不能使用
\uuu dict\uuuuuuu
?为什么
\uu init uuuuuuuuuuu()
设置类属性?@Jakob:我只想获取所有非方法属性,但迪克特给了我一切。如何区分方法和属性之间的dict值?@Sven:我在编写示例时没有考虑到这一点。更改了示例。为什么要这样做?也许有一个更简单的方法来实现你想实现的目标。谢谢,这正是我想要的。只有一个补充:我添加了
和if not type(attr)是staticmethod
,以便也过滤掉静态方法(用于一般目的)。@2rs2ts在
clazz.some\u static\u method
类之间有区别。前者调用描述符get方法,并返回一个可调用的。后者检索不可调用的原始
staticmethod
对象。我会用更干净的替代方案更新答案。