如何知道属性来自哪个类

2024-05-15 22:25:12 发布

您现在位置:Python中文网/ 问答频道 /正文

假设一个类的实例有一个属性attr。我想知道它从哪里得到的属性。你知道吗

让我们考虑一下Python中的两种情况:

class vehicle():
    speed = 5
class flying_machine(vehicle):
    density = 1

以及

class vehicle():
    def __init__(self):
        self.speed = 5
class flying_machine(vehicle):
    def __init__(self):
        super().__init__()
        self.density = 1

如果执行以下代码行:

b = flying_machine()
s = b.speed

s的值为5。两种情况是不同的,在第一种情况下,速度是类“vehicle”的属性,而在另一种情况下,它是类“vehicle”实例的属性。你知道吗

我的问题在这两种情况下都是一样的,我想知道b从哪里得到了他的属性“speed”,我想有一个函数,我可以调用b和“speed”,并把我指向b.speed被定义的地方。你知道吗

在我的示例中,很容易看到b的属性来自何处,但是您可以想象类和子类是跨多个文档定义的,并且具有很长的继承链。例如:

# doc1.py
class vehicle():
    speed = 5

# doc2.py
from doc1.py import *
class flying_machine(vehicle):
     density = 1

# doc3.py
from doc2.py import *
class space_machine(flying_machine):
     light_speed = 0.5

# main.py
from doc3.py import *
c = space_machine()

在最后一个例子中,我的c有一个属性speed,如果我想知道它来自哪里,我必须检查所有以前的导入,在这里有一个函数来显示c.speed来自doc1.py会很有用。你知道吗


Tags: 实例frompyimportself属性initdoc1
1条回答
网友
1楼 · 发布于 2024-05-15 22:25:12

一般来说,我建议您使用一个合适的IDE,比如PyCharm,它允许您单击任何属性,并将您导航到分配该属性的位置。你知道吗

也就是说,通过检查实例及其类的^{}^{},您可以使用类的mro动态提取一些有关属性可能起源于何处的信息:

def lookup(obj, attr):
    if attr in obj.__dict__ or attr in obj.__slots__:
        print('{}: instance attribute'.format(attr))
        klass = next((k for k in obj.__class__.mro() 
                          if '__slots__' in k.__dict__ and attr in k.__slots__), 
                     None)
        if klass:
            print('but expected for class {}'.format(klass))
    else:
        for klass in obj.__class__.mro():
            if attr in klass.__dict__:
                print('{}: class attribute of {}'.format(attr, klass))

可以对任意对象和属性使用此函数:

class Vehicle:
    speed = 5

class Ugly:
    __slots__ = ('look',)
    def __init__(self):
        self.look = 'terrible'

class Car(Ugly, Vehicle):
    def __init__(self):
        super().__init__()
        self.num_wheels = 4

>>> c = Car()

>>> lookup(c, 'speed')
speed: class attribute of <class '__main__.Vehicle'>

>>> lookup(c, 'num_wheels')
num_wheels: instance attribute

>>> lookup(c, 'look')
look: instance attribute
but expected for class <class '__main__.Ugly'>

相关问题 更多 >