• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
孙龙 程序员
少时总觉为人易,华年方知立业难
博客园    首页    新随笔    联系   管理    订阅  订阅
元类
#类也是对象,type创建类的类
def create_class(name):
    if name == "user":
        class User:
            def __str__(self):
                return "user"
        return User
    elif name == "company":
        class Company:
            def __str__(self):
                return "company"
        return Company
    

if __name__ == "__main__":
    MyClass = create_class("user")
    my_obj = MyClass()
    print(type(my_obj))

执行结果:

<class '__main__.create_class.<locals>.User'>

 

def say(self):
    return "i am user"
    # return self.name


class BaseClass():
    def answer(self):
        return "i am baseclass"


if __name__ == "__main__":
    User = type("User", (BaseClass, ), {"name":"user", "say":say})
    my_obj = User()
    print(my_obj)

执行结果:

<__main__.User object at 0x00000000011BD898>

证明了类是type的实例,类也是对象

class User:
    def __new__(cls, *args, **kwargs):
        print (" in new ")
        return super().__new__(cls)
    def __init__(self, name):
        print (" in init")
        pass
a = int()
#new 是用来控制对象的生成过程, 在对象生成之前
#init是用来完善对象的
#如果new方法不返回对象, 则不会调用init函数
if __name__ == "__main__":
    user = User(name="bobby")

执行结果:

in new
in init

 

class MetaClass(type):
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)

from collections.abc import *

#什么是元类, 元类是创建类的类 对象<-class(对象)<-type
class User(metaclass=MetaClass):
    def __init__(self, name):
        self.name = name
    def __str__(self):
        return "user"
if __name__ == "__main__":
  
my_obj = User(name="bobby")
print(my_obj)
 

 

 

------------------------------------------------补充----------------------------------------

先看一下代码:

class MyType(type):
    def __init__(self,*args,**kwargs):
        print('init')
        super(MyType,self).__init__(*args,**kwargs)

    def __call__(self, *args, **kwargs):
        print('call本质:调用类的__new__,再调用类的__init__')
        return super(MyType,self).__call__( *args, **kwargs)


class Foo(metaclass=MyType):
    pass

class Bar(Foo):
    pass

obj = Bar()

执行结果:调用了两次init方法 一次call方法,为什么呢?

class Foo(metaclass=MyType)是type创建的,所以Foo()会执行call方法,实例化会执行init方法
init
init
call本质:调用类的__new__,再调用类的__init__

  

 

对象是由类创建的,类是由type创建的(一切皆对象)

 

Foo类的两种创建方式

# 一切皆对象,类由type创建
class Foo(object):
    pass
等价于
Foo = type('Foo',(object,),{})

  

Foo类也可以由MyType创建

# 一切皆对象,类由MyType创建
class MyType(type):
    pass
Foo = MyType('Foo',(object,),{})

等价于
class Foo(object,metaclass=MyType):
    pass

  

# 一切皆对象,类由MyType创建
class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        return super(MyType, cls).__call__(*args, **kwargs)

Foo = MyType('Foo',(object,),{})

等价于
class Foo(object,metaclass=MyType):
    pass

Foo()

  

另外一种创建方式(函数)with_metaclass(base)

class MyType(type):
    def __init__(self, *args, **kwargs):
        super(MyType, self).__init__(*args, **kwargs)

    def __call__(cls, *args, **kwargs):
        return super(MyType, cls).__call__(*args, **kwargs)


def with_metaclass(base):
    return MyType('XX', (base,), {})


class Foo(with_metaclass(object)):
    pass

  

 

本文来自博客园,作者:孙龙-程序员,转载请注明原文链接:https://www.cnblogs.com/sunlong88/articles/9446053.html

posted on 2018-08-08 22:18  孙龙-程序员  阅读(101)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3