python高级之元类的用法总结

 更新时间:2024年08月19日 10:13:39   作者:敲代码敲到头发茂密  
元类是Python中最高级别的编程概念之一,用于创建类的类,虽然元类在日常Python编程中并不常见,但它们提供了无限的可能性来改变类的行为,从而使元编程成为可能,这篇文章主要给大家介绍了关于python高级之元类的相关资料,需要的朋友可以参考下

一、Type创建类

class A(object):

    def __init__(self, name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        data = object.__new__(cls)
        return data

根据类创建对象

obj=A(‘kobe’)

1、执行类的new方法,创建对象(空对象),【构造方法】 {}

2、执行类的init方法,初始化对象 ,【初始化方法】 {‘name’:‘kobe’}

对象是基于类创建出来的;问题:类是由谁创建的?

类默认是由type创建的

1、传统方式创建类

class A(object):
    v1 = 123

    def func(self):
        return 666


print(A)			#<class '__main__.A'>

2、非传统方式

类名
继承类
成员

A1 = type('A', (object,), {"v1": 123, "func": lambda self: 666})
print(A1)        #<class '__main__.A'>

# 根据类创建对象
obj1 = A1()			#<__main__.A object at 0x0000017049D035E0>
print(obj1)


# 调用对象中的func方法 
print(obj1.func())  #666

类默认由type创建,怎么让一个类的创建改为其他的东西呢? 元类。

二、元类

元类:指定类由谁来创建

1、Foo类由MyType创建,代码如下

class MyType(type):
    pass

# Foo类由MyType创建
class Foo(object, metaclass=MyType):
    pass

2、假设Foo是一个对象,它是由MyType类创建。

class MyType(type):

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

    def __new__(cls, *args, **kwargs):
        # 创建类
        print('new')
        new_cls = super().__new__(cls, *args, **kwargs)
        print(new_cls)
        return new_cls

# 假设Foo是一个对象,由MyType类创建。
class Foo(object, metaclass=MyType):
    pass

执行结果

new
<class '__main__.Foo'>
init

3、类加括号得到的是对象,执行的是__init__()和__new__()方法,对象加括号执行__call__()方法

class F1(object):
    def __init__(self):
        print('init')

    # def __new__(cls, *args, **kwargs):
    #     print('new')

    def __call__(self, *args, **kwargs):
        print(111)

# 类加括号得到的是对象,执行的是__init__和__new__方法
obj = F1()

# 对象加括号执行call方法
obj()

执行结果

init
111

4、假设Foo是一个对象,由MyType创建。

Foo类其实是MyType的一个对象。

Foo() 加括号执行的是——》MyType类中的__call__()方法

__call__()方法实现的功能是:

1、调用自己那个类的__new__方法创建对象

empty_object=self.__new__(self)

2、调用你自己那个类__init__方法去初始化对象

self.__init__(empty_object,*args,**kwargs)3、将创建的对象返回:return empty_object

class MyType(type):

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

    def __new__(cls, *args, **kwargs):
        # 创建类
        print('new')
        new_cls = super().__new__(cls, *args, **kwargs)
        print(new_cls)
        return new_cls

    def __call__(self, *args, **kwargs):
        # 1、调用自己哪个类的__new__方法创建对象
        empty_object=self.__new__(self)
        #2、调用你自己那个类 __init__方法去初始化
        self.__init__(empty_object,*args,**kwargs)

        return empty_object

# 假设Foo是一个对象,由MyType创建。
#  Foo类其实是MyType的一个对象。
# Foo()  ——》MyType对象()
class Foo(object, metaclass=MyType):

    def __init__(self,name):
        self.name=name

v1=Foo('666')

print(v1)
print(v1.name)

三、总结

1、当我们不写MyType类时,Type中已经帮我们定义好了
__init____new____call__ 方法了

当我定义了MyType类时,
__init____new____call__ 方法是我们自己定义的

2、这就是为什么实例化对象的时候,先去创建对象再去初始化对象,Type类中已经实现了先 __new__()__init__()

3、代码从上到下执行,当执行到class Foo(object, metaclass=MyType)

先创建这个类,去MyType中的__new__()创建方法

__init__()实例化方法,类在内存中创建好了,

但是MyType中的__call__()方法是不执行的,因为类后面没有加括号

如果类后面加了括号Foo(),会执行MyType的__call__()方法

4、如果自己定义的类中实现了__call__方法,此时是不会执行的,因为Foo是MyType创建出来的

5、如果要执行Foo类的__call__方法,需要实例化Foo类的对象v1,

然后v1加括号

附:元类的最佳实践和注意事项

最佳实践

仅在必要时使用元类。元类是高级编程工具,通常不需要在日常编程中使用。

考虑继承自type以定义元类,因为type是Python中的内置元类。

在元类的__new__方法中,要返回一个类对象,通常是使用super().__new__来创建它。

注意事项

元类可以控制类的创建和初始化,但要小心不要过度使用,以免使代码变得复杂和难以理解。

在元类中的操作可能会影响所有使用该元类创建的类,因此要小心不要引入意外的副作用。

元类的概念可能对初学者来说有点复杂,建议在熟悉Python的基础之后再深入学习元类。

总结

到此这篇关于python高级之元类用法总结的文章就介绍到这了,更多相关python高级之元类内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 深入理解Python单元测试unittest的使用示例

    深入理解Python单元测试unittest的使用示例

    本篇文章主要介绍了深入理解Python单元测试unittest的使用示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Python获取excel的数据并绘制箱型图和直方图的方法实例

    Python获取excel的数据并绘制箱型图和直方图的方法实例

    这篇文章主要给大家介绍了关于Python获取excel的数据并绘制箱型图和直方图的相关资料,好的图表能帮助我们深化数据的记忆点,文中通过图文以及代码示例将实现的方法介绍的非常详细,需要的朋友可以参考下
    2023-12-12
  • python3实现网络爬虫之BeautifulSoup使用详解

    python3实现网络爬虫之BeautifulSoup使用详解

    这篇文章主要介绍了python3实现网络爬虫之BeautifulSoup使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-12-12
  • Python加密与解密模块hashlib与hmac

    Python加密与解密模块hashlib与hmac

    这篇文章介绍了Python中的加密与解密模块hashlib与hmac,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • 使用python半分钟轻松完成证件照换底色

    使用python半分钟轻松完成证件照换底色

    是不是很多小伙伴儿都不清楚公司是需要蓝底还是红底的证件照,今天小编直接带大家做一款Python换底色的一款小程序,不管什么底色儿,放马过来
    2021-09-09
  • Python Opencv提取图片中某种颜色组成的图形的方法

    Python Opencv提取图片中某种颜色组成的图形的方法

    这篇文章主要介绍了Python Opencv提取图片中某种颜色组成的图形的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • 详解Python3.6安装psutil模块和功能简介

    详解Python3.6安装psutil模块和功能简介

    这篇文章主要介绍了详解Python3.6安装psutil模块和功能简介,详细的介绍了安装psutil模块和该模块的使用,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Python Requests使用Cookie的几种方式详解

    Python Requests使用Cookie的几种方式详解

    这篇文章主要给大家介绍了关于Python Requests使用Cookie的几种方式,Python中的requests库可以使用cookie来维持会话状态,实现登录等操作,需要的朋友可以参考下
    2023-07-07
  • python进行数据预处理的4个重要步骤

    python进行数据预处理的4个重要步骤

    在数据科学项目中,数据预处理是最重要的事情之一,本文详细给大家介绍python进行数据预处理的4个重要步骤:拆分训练集和测试集,处理缺失值,处理分类特征和进行标准化处理,需要的朋友可以参考下
    2023-06-06
  • Python count函数使用方法实例解析

    Python count函数使用方法实例解析

    这篇文章主要介绍了Python count函数使用方法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03

最新评论