如何查找python用户定义类的属性?

时间:2012-06-04 00:28:30

标签: python object

请参阅以下示例代码,该代码位于文件中,例如

classattr.py

class BaseClass(object):
    def __init__(self, param1, param2):
        self.param1 = param1
        self.param2 = param2

    def somemethod(self):
        return "This is returned when I do Base.__dict__"

class ChildOfBaseClass(BaseClass):
    def __init__(self, param1, param2, param3, param4):
        super(ChildOfBaseClass, self).__init__(param1, param2)
        self.param3 = param3
        self.param4 = param4

    def somemethod(self, param3, param4):
        a = param3 + param4
        return a

我希望在创建任何实例之前获取类的所有属性(我假设param1param2等被称为属性)。命令dir(classattr.BaseClass)未列出param1param2。但是,它确实返回方法somemethod

我正在尝试获取属性,原因如下:模块 classattr 导入到另一个文件中,该文件的名称为classattr.BaseClass或{{ 1}}作为某个函数的输入提供。我想确定它在运行时期间是哪一个,然后使用适当的输入(如果是前者,则为classattr.ChildOfBaseClassparam1;如果是param2,则为所有参数param1后者)在创建实例时。我想这样做的方法是检查类是否有param4作为属性,然后使用正确的输入创建实例。还有另一种更好的检查方法吗?另一种方法是将param3param3作为param4中的输入,即使它们不执行任何操作,然后始终使用所有四个参数作为输入创建实例。但这似乎不适合做事。

谢谢。

3 个答案:

答案 0 :(得分:2)

没有真正的方法来获取仅在创建对象后分配的属性名称,例如__init__()中定义的属性,而不实际创建实例。 __init__()方法可以做任何事情,甚至可以通过甚至不在类中的代码进一步修改实例。因此,如果您想知道实例具有哪些属性,则需要一个实例。

答案 1 :(得分:2)

您无法知道类将为其实例提供哪些实例属性,因为它们在创建实例之前不存在。

但是,如果您想要知道在实例化类时需要传递哪些参数,则可以检查类的__init__方法的调用签名以查看它接受的参数。有关获取呼叫签名的一些信息,请参阅Determining the number of parameters in a lambda

请注意,实例属性与__init__参数之间没有固有的关系。你可以有这样一个类:

class Foo(object):
    def __init__(self):
        self.someAttr = 10

。 。 。它定义了一个实例属性而没有接收任何参数。 (反之亦然,这是一个接受参数但不使用它们来创建实例属性的类。)

答案 2 :(得分:1)

BrenBarn的回答指导您一些可能有助于您解决问题的想法。我只是想在术语上添加一些注释。

在Python中,对象的属性是存储在其中的命名值(而对象几乎就是“具有属性的东西”)。它们使用dotted.name语法检索。

Python中的类是对象。因此他们有属性。最重要的是您在class块中定义的所有名称(包括方法),它们成为类对象的属性。因此,当您询问类的属性时,听起来您想要检索类对象本身的属性,实际上并非如此。< / p>

确实dir(classattr.BaseClass)正在做的事情之一就是查找classattr.BaseClass的属性,找到somemethod属性,但找不到param1或{{ 1}}因为它们是类对象 param2属性;这些实例创建并初始化后,它们(将是)BaseClass实例的属性。

但是你真正似乎要问的是如何找出给定类的BaseClass方法的调用签名。正如BrenBarn所指出的那样,虽然类经常编写,只是直接从__init__的参数初始化它们的实例属性,但绝对不能保证是这种情况。但是,如果您的目的只是为了知道要传递给类以创建实例的信息,那么您不需要知道(并且不应该关心)将最终存储为属性的内容,而只是知道什么是__init__方法的必需参数。