首页 > 编程语言 >python元类

python元类

时间:2024-03-05 10:37:28浏览次数:32  
标签:__ python self 元类 init kwargs new Foo

python 元类

class Car(object):
    def __init__(self,name):
        print('init')
        self.name=name
    def __new__(cls, *args, **kwargs):
        print('new')
        return super().__new__(cls)
    
obj = Car('雪佛兰')

# 输出
# new
# init
根据类创建对象 obj = Car('雪佛兰')
  1. 执⾏类的 new ⽅法, 创建空对象 【构造⽅法】 {}

  2. 执⾏类的 init ⽅法,初始化对象 【初始化⽅法】

问:对象是类创建的,类是谁创建的?

答:类是由type创建。

type创建类

# 传统⽅式创建类
class Foo(object):
    v1 = 123
 	def func(self):
 		return 666
    
# ⾮传统⽅式创建类
Fa = type("Foo", (object,),{"v1": 123, "func":lambda self:666})
# 1 创建类 
# 参数        - 类名 - 继承类 - 成员
# 2 根据类创建对象
obj = Fa()
# 3 调⽤对象中的v1变量
print(obj.v1)
# 4 执⾏对象中的func⽅法
result = obj.func()

metaclass 元类

class MyType(type):
    pass
class Foo(object, metaclass=MyType):
    pass
# Foo类由MyType创建
class MyType(type):
    def __init__(self, *args, **kwargs):
        print('init')
        super().__init__(*args, **kwargs)

    def __new__(cls, *args, **kwargs):
        print('new')
        return super().__new__(cls, *args, **kwargs)

    def __call__(self, *args, **kwargs):
        print('call')
        # 调⽤⾃⼰的那个类 __new__ ⽅法去创建对象
        empty_object = self.__new__(self)
        # 调⽤你⾃⼰的 __init__ ⽅法取初始化
        self.__init__(empty_object, *args, **kwargs)
        return empty_object

class Foo(object, metaclass=MyType):
    def __init__(self, name):
        print('foo init')
        self.name = name

    def __new__(cls, *args, **kwargs):
        print('foo new')
        return super().__new__(cls, *args, **kwargs)
obj = Foo('ifan')

## class Foo(object, metaclass=MyType):
#      ....
#   执行到这一步 会调用 type的 call方法 在call方法中先调用 类的 new,在调用 类的 init
#  class Foo():... => type call() =>  mytype new()  => mytype init()
#  输出 new init


## obj = Foo('ifan')
#  obj对象 由Foo类创建,Foo类(对象)由Mytype类创建
#  调用 Foo('ifan')  => Mytype call() => Foo new() => Foo init()
#  输出 call   foo new    foo init


## obj() =>  Foo call()

元类创建 单例模式

class myType(type):
    def __init__(self, *args, **kwargs):
        super().__init__( *args, **kwargs)
        self.instance=None
        
    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, *args, **kwargs)
    
    def __call__(self, *args, **kwargs):
        if not self.instance:
            self.instance = self.__new__(self)
        self.__init__(self.instance, *args, **kwargs)
        return self.instance

class per(metaclass=myType):
    pass
a = per()
b = per()
print(a,b)

标签:__,python,self,元类,init,kwargs,new,Foo
From: https://www.cnblogs.com/lijun-goods/p/18053401

相关文章

  • Python工具箱系列(五十)
    使用PIL加工图片 常见的图片操作包括但不限于:•大小进行变化•旋转•翻转•使用滤镜进行处理•剪切   以下python代码演示了如何将一幅美女图进行多种加工处理,并且汇集在一起,形成一个类似于照片墙的相关操作。fromPILimportImagefromPILimportImageFilterf......
  • python与人工智能
    由于无文化是机器学习学是大模型一些就用开发,大部份教学都是python方便实验,就导致了要对python第二遍在过一下相关知识,虽然10年前学一遍python和web开发,估记也忘记差不多了,主要是针对ES文件检索,向量数据库,字符串处理,ESP32 fask这些也不太熟了,所以整理一下pythonAI应用开发......
  • python 语法之 print 函数和 input 函数
    print函数input函数案例一:圆的周长importmaths=input("圆的半径:\n")s=float(s)c=2*math.pi*sprint(f"圆的周长,{c:.2f}")w=input("请输入天气情况(可选项:晴、阴):")ifw=="晴天":print("play")else:print(f"天气{w}不玩")......
  • python益智游戏五子棋的二次创新
    五子棋是一种源自中国的传统棋类游戏,起源可以追溯到古代。它是一种两人对弈的游戏,使用棋盘和棋子进行。棋盘通常是一个15×15的网格,棋子分为黑白两色,双方轮流在棋盘上落子。游戏的目标是通过在棋盘上落子,使自己的五个棋子在横向、纵向或斜向形成连续的线路,从而获胜。五子棋被认......
  • WSGI介绍:Python 首先了解
    1.1什么是WSGI首先介绍几个关于WSGI相关的概念WSGI:全称是WebServerGatewayInterface,WSGI不是服务器,python模块,框架,API或者任何软件,只是一种规范,描述webserver如何与webapplication通信的规范。server和application的规范在PEP3333中有具体描述。要实现WSGI协议,必须同时实......
  • python-pip更改下载路径,解决超时问题
    有时pip安装包时,会提示pip._vendor.urllib3.exceptions.ReadTimeoutError:HTTPSConnectionPool(host='files.pythonhosted.org',port=443):Readtimedout.原因跟解决方式PyPI镜像:考虑使用PyPI的镜像站点。中国用户经常遇到与files.pythonhosted.org的连接问题,因此他们经常......
  • python内置方法(重点)
    方法作用示例输出upper全部大写"hello".upper()"HELLO"lower全部小写"Hello".lower()"hello"startswith()是否以a开头"Yuan".startswith("Yu")Trueendswith()是否以a结尾"Yuan".endswith("a&qu......
  • python运算符
    【1】算数运算符运算符说明实例结果+加1+12-减1-10*乘1*33/除法(和数学中的规则一样)4/22//整除(只保留商的整数部分)7//23%取余,即返回除法的余数7%21**幂运算/次方运算,即返回x的y次方2**416,即24【2】赋值运算符......
  • python数据类型与字符串常用方法
    int-py2中有:int/long;py3中有int。-强制转换:int(''76"")-除法:py2(多加一行代码)和py3(正常)boolTrue/False(其他语言:true/false)特殊为False的其他类型:0和""str独有功能upper/lowerreplacestrip/lstrip/rstripisdigitsplit/r......
  • python基础语法
    (1)注释注释就是对代码的解释和说明,其目的是让人们能够更加轻松地了解代码。注释是编写程序时,写程序的人给一个语句、程序段、函数等的解释或提示,能提高程序代码的可读性。一般情况下,合理的代码注释应该占源代码的1/3左右。注释只是为了提高公认阅读,不会被解释器执行。Python......