简体   繁体   English

在Python中调用cls object的构造函数

[英]Call constructor of cls object in Python

I am trying to call the constructor of a class object in python. I managed to get it to work using the following few lines:我试图在 python 中调用class object 的构造函数。我设法使用以下几行使其工作:

obj = cls.__new__(cls)
n = (List of attribute names)
v = (List of attribute values)

for s in n:
    setattr(obj, s, v[s])

I was wondering if there is a way to directly insert the attribute value + name pairs into the constructor, cause the arguments are just ignored if i call the following:我想知道是否有一种方法可以直接将属性值 + 名称对插入到构造函数中,因为如果我调用以下命令,arguments 将被忽略:

obj = cls.__new__(cls, v)

ps: I am using python3 ps:我用的是python3

The class looks similar to this: class 看起来与此类似:

class InheritingClass(BaseClass):
    def __init__(self, basic_attribute, another_attribute=None):
        super().__init__(basic_attribute=basic_attribute)
        self.another_attribute= another_attribute

class BaseClass:
    def __init__(self, basic_attribute=1):
       self.basic_attribute= basic_attribute

So nothing special there所以没什么特别的

__init__ is the constructor of Python class instead of __new__ . __init__是Python类的构造函数,而不是__new__ Refer Pythons use of new and init for more information. 有关更多信息,请参阅Pythons使用new和init

To add, if you want to store arbitrary attributes to your class, you can use dict.update like so: 要添加,如果要将任意属性存储到类中,可以像这样使用dict.update

class BaseClass:
    def __init__(self, basic_attribute=1, **kw):
        self.basic_attribute = basic_attribute
        self.__dict__.update(**kw)


class InheritingClass(BaseClass):
    def __init__(self, basic_attribute, another_attribute=None, **kw):
        super().__init__(basic_attribute=basic_attribute, **kw)
        self.another_attribute = another_attribute

Then: 然后:

ic = InheritingClass('hi', a=1, b=20)
print(ic.a, ic.b)  # prints 1, 20

I was wondering if there is a way to directly insert the attribute value + name pairs into the constructor 我想知道是否有一种方法可以直接将属性值+名称对插入构造函数中

Please don't do that. 请不要这样做。 This would be the anti pattern. 这将是反模式。 Instead, use the __init__ method to set the values. 而是使用__init__方法设置值。 The __new__ method should be the memory space allocation that returns the object instance, obj in your case. __new__方法应该是返回对象实例的内存空间分配,在您的情况下是obj

So you should probable better do this inside your __init__ : 所以你应该在你的__init__做得更好:

k = ['a', 'b', 'c']
v = [1, 2, 3]
d = dict(zip(k, v))

class C:
    def __init__(self, d):                
        for _ in d:            
            setattr(self, _, d[_])

ci=C(d)
print(ci.a) # 1

I used the dict as __init__ parameter, where I used the zip method to create one. 我使用dict作为__init__参数,我使用zip方法创建一个。

To answer the question "How do you call the constructor on a class object?"回答问题“如何调用 class object 上的构造函数?” you need to look at the comments from Amadan way back on Aug 24, 2016 at 6:41.您需要查看 Amadan 于 2016 年 8 月 24 日 6:41 发表的评论。

The answer:答案:

new_obj = cls()

Here's some example code that illustrates the point:下面是一些示例代码,说明了这一点:

class C:
    @classmethod
    def c(cls):
        return cls()
    
c = C.c()
print(c) # displays <__main__.C object at 0x10ef16a90>

class D(C):
    pass
d = D.c()
print(d) # displays <__main__.D object at 0x10ef16370>

And so we see that you can instantiate an object from the cls object.所以我们看到您可以从 cls object 实例化一个 object。

Now if we combine Amadan's comment with prosti's cool code for setting attributes, we get this:现在,如果我们将 Amadan 的注释与 prosti 用于设置属性的酷代码结合起来,我们会得到:

class ObjectFactory:
    @classmethod
    def new(cls,**kwargs):
        return cls(**kwargs)

    def __init__( self, **kwargs ):
      for _ in kwargs:
        setattr( self, _ , kwargs[ _ ] )

class Person(ObjectFactory):

    pass

person = Person.new( first = "John", last = "Doe" )

print(person)            # <__main__.Person object at 0x10fe49ff0>
print(person.__dict__)   # {'first': 'John', 'last': 'Doe'}

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

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