【问题标题】:How to find attributes of a python user-defined class?如何查找python用户定义类的属性?
【发布时间】:2012-06-05 00:36:19
【问题描述】:

请看下面的示例代码,它在一个文件中,比如说

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.BaseClassclassattr.ChildOfBaseClass 提供为某个函数的输入。我想在运行时确定它是哪一个,然后在创建实例时使用适当的输入(param1param2,如果是前者,或者所有参数param1param4,如果是后者)。我正在考虑这样做的方式是检查该类是否具有 param3 作为属性,然后使用正确的输入创建实例。还有其他更好的检查方法吗?另一种方法是将param3param4 作为BaseClass 中的输入,即使它们不执行任何操作,然后始终使用所有四个参数作为输入来创建实例。但这似乎不是合适的做事方式。

谢谢。

【问题讨论】:

    标签: python object


    【解决方案1】:

    您无法知道一个类将赋予其实例哪些实例属性,因为在创建实例之前它们并不存在。

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

    请注意,实例属性和__init__ 参数之间没有内在关系。你可以有这样的课程:

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

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

    【讨论】:

    • 感谢您的链接。在我的情况下,如何将您提供的链接中所述的方法应用于 init 函数。例如,我尝试了`inspect.getargspec(classattr.BaseClass)。我收到一条错误消息,说 BaseClass 不是函数。谢谢!
    • 错误信息告诉你究竟出了什么问题。类与其__init__ 方法不同。您必须致电inspect.getargspec(classattr.BaseClass.__init__)
    • 太棒了。阅读错误后,我尝试了 inspect.getargspec(classattr.BaseClass.__init__()) ,这也给出了错误。您的解决方案效果很好。谢谢。
    【解决方案2】:

    没有真正的方法来获取仅在创建对象后分配的属性名称,例如在__init__() 中定义的属性名称,而无需实际创建实例。 __init__() 方法可以做任何事情,并且一个实例可能已经被甚至不在类中的代码进一步修改。所以如果你想知道一个实例有什么属性,你需要一个实例。

    【讨论】:

      【解决方案3】:

      BrenBarn 的回答为您提供了一些可以帮助您解决问题的想法。我只是想添加一些关于术语的注释。

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

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

      确实,dir(classattr.BaseClass) 正在做的一件事是查找classattr.BaseClass 的属性,它会在其中找到somemethod 属性,但没有找到param1param2,因为它们是 类对象的属性 BaseClass;一旦创建和初始化了这些实例,它们(将是)BaseClassinstances 的属性。

      但您真正似乎要问的是如何找出给定类的__init__ 方法的调用签名。正如 BrenBarn 所指出的,尽管编写类经常只是为了简单地从 __init__ 的参数直接初始化其实例的属性,但绝对不能保证确实如此。但是,如果您的目的只是为了知道要传递给类以创建实例的信息,那么您不需要知道(也不应该关心)最终将存储为属性的内容,而只是知道什么是__init__ 方法的必需参数。

      【讨论】:

      • 有没有办法找到 init 方法所需的参数?谢谢。
      • @Curious2learn BrenBarn 的答案包含一个链接,其中包含有关获取函数调用签名的信息。
      猜你喜欢
      • 1970-01-01
      • 2020-03-14
      • 2021-06-16
      • 1970-01-01
      • 2022-01-10
      • 1970-01-01
      • 2011-12-18
      • 2018-02-16
      • 1970-01-01
      相关资源
      最近更新 更多