python元编程3【type类继承和__new__,__init__参数传递】【new的参数移除操作】

  1. 源码学习

class SetterAwareType(type):    # 元类
    def __new__(cls, *args):
        # print('in SetterAwareType __new__')
        # print(type(type.__new__(cls, 'hehehe',(object,), {})))
        return type.__new__(cls, 'hehehe',(object,), {})  # 'name' 直接传入了

    def __init__(cls,  *args):
        '''
        # 这里的init不是self,传入的是__new__类似的,打印print(cls, args)结果如下
        1. a = ModelObject()
        2. class C(a)
        1. <class '__main__.hehehe'> ()
        2. <class '__main__.hehehe'> ('C', (<class '__main__.hehehe'>,), {'__module__': '__main__', '__qualname__': 'C', '__init__': <function C.__init__ at 0x000001B83DDC68B8>})
        '''
        # print(cls, args)
        # print('in SetterAwareType __init__')
        # return super(SetterAwareType, cls).__init__(cls,  *args)   # 创建 class C(a) 时候报错 type.__init__() takes 1 or 3 arguments
        return super(SetterAwareType, cls).__init__(cls, )
        # return type.__init__(cls, *args)                    # TypeError: type.__init__() takes 1 or 3 arguments


class ModelObject(SetterAwareType):
    def test(self):
        print('in ModelObject copy')

a = ModelObject()  # _init__ 参数 <class '__main__.hehehe'> ()

class C(a): # _init__ 参数 <class '__main__.hehehe'> ('C', (<class '__main__.hehehe'>,), {'__module__': '__main__', '__qualname__': 'C', '__init__': <function C.__init__ at 0x000002445ED868B8>})
    pass

print(type(SetterAwareType))  #  type 元类
print(type(ModelObject))      #  type 元类

print('a', a)
print(type(a))    # a 是class hehehe,属于ModelObject class

b=a()
print('b', b)
print(type(b))    # b 是obj hehehe,属于hehehe class


a.test()          # 类中的函数
# b.test()        #obj中报错 # AttributeError: 'hehehe' object has no attribute 'test'

c = C()
# c.test()          # AttributeError: 'hehehe' object has no attribute 'test'

  1. new的正确使用【需要移除】
https://stackoverflow.com/questions/59217884/new-method-giving-error-object-new-takes-exactly-one-argument-the-typ

Your code should be something like

class Foo:
    def __new__(cls, a, b, *args, **kwargs):
        print("Creating Instance")
        instance = super(Foo, cls).__new__(cls, *args, **kwargs)
        return instance

    def __init__(self, a, b, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.a = a
            self.b = b
This definition removes your new parameters a and b from args before passing it on to whoever is next on the MRO. Likewise for __init__.
posted @ 2021-03-31 09:29  该显示昵称已被使用了  阅读(125)  评论(0编辑  收藏  举报