简体   繁体   English

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

[英]How to find attributes of a python user-defined class?

Please see the following example code, which is in a file, say 请参见文件中的以下示例代码,例如

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

I want to get all the attributes (I am assuming that param1 , param2 etc. are called attributes) of the classes before I create any instance. 我想在创建任何实例之前获取类的所有属性(假设param1param2等称为属性)。 Command dir(classattr.BaseClass) does not list param1 and param2 . 命令dir(classattr.BaseClass)没有列出param1param2 It, however, does return the method somemethod . 但是,它确实返回了somemethod方法。

I am trying to get the attributes for the following reason: The module classattr is imported in another file where the name of the class, either classattr.BaseClass or classattr.ChildOfBaseClass is provided as an input to some function. 我正由于以下原因而尝试获取属性:模块classattr导入另一个文件,该文件中提供了类名称classattr.BaseClassclassattr.ChildOfBaseClass作为某些函数的输入。 I want to determine which one it is during the runtime and then use appropriate inputs (either param1 and param2 if the former, or all the parameters param1 to param4 if the latter) when creating the instance. 我想确定它在运行时是哪个,然后在创建实例时使用适当的输入(如果是前者,则使用param1param2如果是后者,则使用所有参数param1param4 )。 The way I was thinking of doing this is to check whether the class has param3 as an attribute and then creating the instance with correct inputs. 我想到的方法是检查类是否具有param3作为属性,然后使用正确的输入创建实例。 Is there another better way to check? 还有另一种更好的检查方法吗? Another way is to have param3 and param4 as inputs in BaseClass even if they do not do anything and then always create instance with all four parameters as inputs. 另一种方法是将param3param4用作BaseClass输入,即使它们不执行任何操作,然后始终使用所有四个参数作为输入来创建实例。 But that does not seems appropriate way of doing things. 但这似乎不是适当的处理方式。

Thank you. 谢谢。

There's no real way to get the names of attributes that are only assigned after the object is created, such as those defined in __init__() , without actually creating the instance. 没有真正的方法来获取仅在创建对象后才分配的属性名称,例如__init__()定义的属性名称,而无需实际创建实例。 The __init__() method can do anything at all, and an instance might have been even further amended by code that's not even in the class. __init__()方法根本不能做任何事情,并且实例甚至可能被类中甚至没有的代码进一步修改。 So if you want to know what attributes an instance has, you need an instance. 因此,如果您想知道实例具有哪些属性,则需要一个实例。

You can't know what instance attributes a class will give to its instances, because they don't exist before an instance is created. 您无法知道类将为其实例赋予哪些实例属性,因为它们在创建实例之前不存在。

However, if what you want is to know what parameters you need to pass when instantiating the class, you can inspect the call signature of the class's __init__ method to see what parameters it accepts. 但是,如果您想知道实例化该类时需要传递哪些参数,则可以检查该类的__init__方法的调用签名,以了解它接受哪些参数。 See Determining the number of parameters in a lambda for some information about getting the call signature. 有关获取呼叫签名的一些信息,请参阅确定lambda中的参数数量

Note that there's no inherent relationship between instance attributes and __init__ parameters. 请注意,实例属性和__init__参数之间没有固有的关系。 You could have a class like this: 您可以有一个像这样的课程:

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

. . . which defines an instance attribute without receiving any parameters. 它定义实例属性而不接收任何参数。 (Or vice versa, a class that accepts parameters but doesn't use them to create instance attributes.) (反之亦然,一个接受参数但不使用它们创建实例属性的类。)

BrenBarn's answer directs you to some ideas that might help you solve your problem. 布伦·巴恩(BrenBarn)的答案将引导您找到可能有助于您解决问题的一些想法。 I just thought I'd add some notes on terminology. 我只是认为我会在术语上添加一些注释。

In Python, the attributes of an object are the named values stored within it (and an object is pretty much nothing more and nothing less than "a thing that has attributes"). 在Python中,对象的属性是存储在其中的命名值(对象几乎就是“具有属性的事物”。 They are retrieved with the dotted.name syntax. 使用dotted.name语法检索它们。

Classes in Python are objects. Python中的类是对象。 They therefore have attributes. 因此,它们具有属性。 The most important ones are all the names that you defined in the class block (including the methods), which become attributes of the class object. 最重要的是您在class块中定义的所有名称(包括方法),这些名称将成为类对象的属性。 So when you ask about the attributes of a class, it sounds like you're wanting to retrieve the attributes of the class object itself , which is not actually the case. 因此,当您询问类的属性时,听起来好像您想检索类对象本身的属性,实际上并非如此。

Indeed one of the things dir(classattr.BaseClass) is doing is looking up the attributes of classattr.BaseClass , where it finds the somemethod attribute, but does not find param1 or param2 because they are not attributes of the class object BaseClass ; 的确, dir(classattr.BaseClass)所做的一件事情就是查找classattr.BaseClass的属性,在该属性中找到somemethod属性,但找不到param1param2因为它们不是 类对象 BaseClass属性; they (will be) attributes of instances of BaseClass once those instances have been created and initialised. 一旦实例被创建和初始化,它们(将是) BaseClass 实例的属性。

But what you really seem to be asking about is how to find out the call signature of the __init__ method of a given class. 但是,您似乎真正要问的是如何找出给定类的__init__方法的调用签名。 As noted by BrenBarn, although classes are often written to simply directly initialise their instances' attributes from the arguments to __init__ , there is absolutely no guarantee that this is the case. 正如BrenBarn所指出的那样,尽管编写类通常是为了简单地从__init__的参数中直接初始化其实例的属性,但绝对不能保证是这种情况。 But if your purpose is just to know what information to pass to a class in order to create an instance, then you don't need to know (and shouldn't care) what will end up being stored as attributes, but rather just what are the required parameters to the __init__ method. 但是,如果您的目的只是想知道要传递给类以创建实例的哪些信息,那么您就不必知道(也不必在意)将最终存储为属性的内容,而只需知道是__init__方法的必需参数。

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

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