简体   繁体   English

获取实例的类名

[英]Getting the class name of an instance

How do I find out the name of the class used to create an instance of an object in Python?如何找出用于在 Python 中创建对象实例的类的名称?

I'm not sure if I should use the inspect module or parse the __class__ attribute.我不确定我是应该使用inspect模块还是解析__class__属性。

Have you tried the __name__ attribute of the class?你试过类的__name__属性吗? ie type(x).__name__ will give you the name of the class, which I think is what you want.type(x).__name__会给你类的名字,我认为这是你想要的。

>>> import itertools
>>> x = itertools.count(0)
>>> type(x).__name__
'count'

If you're still using Python 2, note that the above method works with new-style classes only (in Python 3+ all classes are "new-style" classes).如果您仍在使用 Python 2,请注意上述方法仅适用于新式类(在 Python 3+ 中,所有类都是“新式”类)。 Your code might use some old-style classes.您的代码可能会使用一些旧式类。 The following works for both:以下适用于两者:

x.__class__.__name__

你想要类名作为字符串吗?

instance.__class__.__name__

type() ? type()

>>> class A:
...     def whoami(self):
...         print(type(self).__name__)
...
>>>
>>> class B(A):
...     pass
...
>>>
>>>
>>> o = B()
>>> o.whoami()
'B'
>>>
class A:
  pass

a = A()
str(a.__class__)

The sample code above (when input in the interactive interpreter) will produce '__main__.A' as opposed to 'A' which is produced if the __name__ attribute is invoked.上面的示例代码(在交互式解释器中输入时)将生成'__main__.A' ,而不是调用__name__属性时生成'A' By simply passing the result of A.__class__ to the str constructor the parsing is handled for you.只需将A.__class__的结果传递给str构造函数,即可为您处理解析。 However, you could also use the following code if you want something more explicit.但是,如果您想要更明确的内容,也可以使用以下代码。

"{0}.{1}".format(a.__class__.__module__,a.__class__.__name__)

This behavior can be preferable if you have classes with the same name defined in separate modules.如果您在单独的模块中定义了具有相同名称的类,则此行为可能更可取。

The sample code provided above was tested in Python 2.7.5.上面提供的示例代码在 Python 2.7.5 中进行了测试。

In Python 2,在 Python 2 中,

type(instance).__name__ != instance.__class__.__name__
# if class A is defined like
class A():
   ...

type(instance) == instance.__class__
# if class A is defined like
class A(object):
  ...

Example:例子:

>>> class aclass(object):
...   pass
...
>>> a = aclass()
>>> type(a)
<class '__main__.aclass'>
>>> a.__class__
<class '__main__.aclass'>
>>>
>>> type(a).__name__
'aclass'
>>>
>>> a.__class__.__name__
'aclass'
>>>


>>> class bclass():
...   pass
...
>>> b = bclass()
>>>
>>> type(b)
<type 'instance'>
>>> b.__class__
<class __main__.bclass at 0xb765047c>
>>> type(b).__name__
'instance'
>>>
>>> b.__class__.__name__
'bclass'
>>>

Alternatively you can use the classmethod decorator:或者,您可以使用classmethod装饰器:

class A:
    @classmethod
    def get_classname(cls):
        return cls.__name__

    def use_classname(self):
        return self.get_classname()

Usage :用法

>>> A.get_classname()
'A'
>>> a = A()
>>> a.get_classname()
'A'
>>> a.use_classname()
'A'

Good question.好问题。

Here's a simple example based on GHZ's which might help someone:这是一个基于 GHZ 的简单示例,可能对某人有所帮助:

>>> class person(object):
        def init(self,name):
            self.name=name
        def info(self)
            print "My name is {0}, I am a {1}".format(self.name,self.__class__.__name__)
>>> bob = person(name='Robert')
>>> bob.info()
My name is Robert, I am a person

Apart from grabbing the special __name__ attribute, you might find yourself in need of the qualified name for a given class/function.除了获取特殊的__name__属性外,您可能会发现自己需要给定类/函数的限定名称 This is done by grabbing the types __qualname__ .这是通过获取类型__qualname__来完成的。

In most cases, these will be exactly the same, but, when dealing with nested classes/methods these differ in the output you get.在大多数情况下,它们是完全相同的,但是,在处理嵌套类/方法时,它们的输出会有所不同。 For example:例如:

class Spam:
    def meth(self):
        pass
    class Bar:
        pass

>>> s = Spam()
>>> type(s).__name__ 
'Spam'
>>> type(s).__qualname__
'Spam'
>>> type(s).Bar.__name__       # type not needed here
'Bar'
>>> type(s).Bar.__qualname__   # type not needed here 
'Spam.Bar'
>>> type(s).meth.__name__
'meth'
>>> type(s).meth.__qualname__
'Spam.meth'

Since introspection is what you're after, this is always you might want to consider.由于内省是您所追求的,因此您可能始终需要考虑这一点。

To get instance classname:获取实例类名:

type(instance).__name__

or或者

instance.__class__.__name__

both are the same两者都是一样的

You can simply use __qualname__ which stands for qualified name of a function or class您可以简单地使用__qualname__代表函数或类的限定名称

Example:例子:

>>> class C:
...     class D:
...         def meth(self):
...             pass
...
>>> C.__qualname__
'C'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__qualname__
'C.D.meth'

documentation link qualname文档链接qualname

You can first use type and then str to extract class name from it.您可以先使用type然后str从中提取 class 名称。

class foo:pass;

bar:foo=foo();
print(str(type(bar))[8:-2][len(str(type(bar).__module__))+1:]);

Result结果

foo

If you're looking to solve this for a list (or iterable collection) of objects, here's how I would solve:如果你想为对象列表(或可迭代集合)解决这个问题,我会这样解决:

from operator import attrgetter

# Will use a few data types to show a point
my_list = [1, "2", 3.0, [4], object(), type, None]

# I specifically want to create a generator
my_class_names = list(map(attrgetter("__name__"), map(type, my_list))))

# Result:
['int', 'str', 'float', 'list', 'object', 'type', 'NoneType']


# Alternatively, use a lambda
my_class_names = list(map(lambda x: type(x).__name__, my_list))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM