元类

一、exec

exec(object,globals,locals)中有三个参数:
object:字符串形式的命令,即一段字符串形式的代码
globals:全局作用域,必须是字典形式的;如不指定,默认为globals
locals:局部作用域,必须是字典;如不指定,默认locals

g = {'x':1,'y':2}
l = {}
exec('''
global x,m
x = 100
m = 10
z = 50
    ''',g,l)

print(g)
print(l)

二、对象的特性

在python中一切皆对象,用对象将python中所有的变量、函数等统一起来,是有与它们都有共同的特性:
1、都可以被引用,x = obj
2、都可以当做返回值(python中返回值可是一任何类型)
3、都可以当函数的参数传入
4、都可以当做容器类的元素,如列表,字典等容器同样具备上面四种属性的都是对象。

三、元类定义

class Foo:
    pass

f = Foo()
print(type(Foo))
print(type(f))
打印结果:
<class 'type'>
<class '__main__.Foo'>

由上面程序结果可以看出,f是由Foo这个类实例化得到,而Foo则是由type实例化得到的。因此type也是一个类,即Foo是以type这个类为模板,得到的类。此时type就是Foo的元类。类的类就是元类,元类时类的模板。
type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象。

四、创建对象的两种方式

1、使用class关键字

class Chinese(object):
    country='China'
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def talk(self):
        print('%s is talking' %self.name)

2、手动模拟class创建类的过程

将创建类的步骤拆分开,手动去创建。即type模式

# 定义类的三要素
# 1、类名
class_name = 'Chinese'
# 2、父类
class_bases = (object,)               # 不加逗号,会报错
# 3、名称空间
class_body = '''
country='China'
def __init__(self,name,age):          # 类体代码,字符串形式
    self.name=name
    self.age=age
def talk(self):
    print('%s is talking' %self.name)
'''

class_dict = {}                       # 分配类的名称空间
exec(class_body,globals(),class_dict) # 调用exec()创建类
# print(class_dict)

Chinese = type(class_name,class_bases,class_dict)  # 创建元类为type的类
print(Chinese)

p = Chinese('夏天',18)               # 实例化
print(p)
print(p,p.name,p.age)
p.talk()

type 接收三个参数:
第 1 个参数是字符串 Chinese,表示类名
第 2 个参数是元组 (object, ),表示所有的父类
第 3 个参数是字典,这里是一个空字典,表示没有定义属性和方法
补充:若Chinese类有继承,即class Chinese(Bar):… 则等同于type(‘Chinese’,(Bar,),{})

五、定制元类控制类的行为

class Mymeta(type):     # 定义一个继承type类的元类

    def __init__(self,class_name,class_bases,class_dict):
        if not class_name.istitle():
            raise TypeError('首字母必须大写')            # raise抛异常关键字,有异常程序运行到此就结束了
        # print(class_dict)                              # 查看类的名称空间
        if not '__doc__' in class_dict or not class_dict['__doc__'].strip():    #控制创建类的行为
            raise TypeError('必须有注释,且注释不能为空')


        super(Mymeta,self).__init__(class_name,class_bases,class_dict)  # 创建类的三要素


class Chinese(object,metaclass= Mymeta):   # metaclass= Mymeta表示定义了Chinese的元类是Mymeta
    '''
    中国人的类
    '''
    country = 'Chia'
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def talk(self):
        print('%s is talking' %self.name)

六、定制元类控制类的实例化

1、__call__方法

# __call__方法介绍
class Foo:

    def __call__(self, *args, **kwargs):   # 定义一个__call__方法使产生对象也能被调用,如果没有__call__方法对象则不能被调用
        print(self)
        print(args)
        print(kwargs)

obj = Foo()
# 元类type内部也有一个__call__方法
obj(1,2,3,a = 5,b = 6)

2、控制类的实例化

class Mymeta(type):     # 定义一个继承type类的元类

    def __init__(self,class_name,class_bases,class_dict):
        if not class_name.istitle():
            raise TypeError('首字母必须大写')

        if not '__doc__' in class_dict or not class_dict['__doc__'].strip():
            raise TypeError('必须有注释,且注释不能为空')
        super(Mymeta,self).__init__(class_name,class_bases,class_dict)

    def __call__(self, *args, **kwargs):
        print('触发__call__')

    # __call__方法触发后 ,进行的三部曲:
    # 1、产生一个空对象china
        obj = object.__new__(self)  #  self = Chinese
    # 2、初始化空对象china,即触发__init__方法
        self.__init__(obj,*args, **kwargs)
    # 3、返回china对象
        return obj

class Chinese(object,metaclass= Mymeta):
    '''
    中国人的类
    '''
    country = 'Chia'
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def talk(self):
        print('%s is talking' %self.name)

china = Chinese('夏天',18)
'''
     Chinese('夏天',18)=Chinese. __call__(Chinese, '夏天',18) ,Chinese可以理解为是经过Mymeta这个元类实例化得到的 一个对象
     当调用Chinese('夏天',18)时就触发了Mymeta内部的__call__方法,将Chinese传给了self,'夏天'和18传给了后面的参数。在实例化时
     会经过三个步骤:1、创建一个空对象;2、将空对象初始化,即触发__init__方法;3、有返回值
'''

print(china.__dict__)

3、自定义元类控制实例化应用

(1)单例模式

将参数都一样的不同对象,将他们的内存空间整合成一个内存空间,即在每个对象生成时,申请的内存空间相同。

class MySQL:

    _instance = None

    def __init__(self):
        self.host = '127.0.0.1'
        self.port = 3306

    @classmethod
    def singleton(cls):
        if not cls._instance:
            obj = cls()
            cls._instance = obj
        return  cls._instance
    def conn(self):
        pass

    def execte(self):
        pass

obj1 = MySQL.singleton()
obj2 = MySQL.singleton()
obj3 = MySQL.singleton()
print(id(obj1))
print(id(obj2))
print(id(obj3))
print(obj1 is obj2 is obj3)

(2)用元类方式实现单例模

class Mymeta(type):     # 定义一个继承type类的元类

    def __init__(self,class_name,class_bases,class_dict):
        if not class_name.istitle():
            raise TypeError('首字母必须大写')

        if not '__doc__' in class_dict or not class_dict['__doc__'].strip():
            raise TypeError('必须有注释,且注释不能为空')
        super(Mymeta,self).__init__(class_name,class_bases,class_dict)
        self._instance = None # 设置MySQL类的_instance属性

    def __call__(self, *args, **kwargs):
        if not self._instance:  # 判断类里面有没有_instance属性,没有就实例化一个对象
                obj = object.__new__(self)
                self.__init__(obj)
                self._instance = obj
        return self._instance

class Mysql(object,metaclass=Mymeta):
    '''
    MySQL
    '''

    _instance = None

    def __init__(self):
        self.host = '127.0.0.1'
        self.port = 3306

    def conn(self):
        pass

    def execte(self):
        pass

obj1 = Mysql()
obj2 = Mysql()
obj3 = Mysql()

print(obj1 is obj2 is obj3)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值