python元类单例_元类\单例模式

元类类的爹就是元类 #很通俗易懂

而再python中又有一切皆对象说法

那么类是如何成为对象的呢?即调用元类,得到对象(类,或者说自定义的类)

默认的元类的type,默认情况下我们用class关键字定义的类都是由type产生的

# python中一切皆对象

# 元类介绍

# 元类=>OldboyTeacher类 =>obj 对象

class OldboyTeacher(object):

school = 'oldboy'

def __init__(self, name, age):

self.name = name

self.age = age

def say(self):

print('>>>>')

obj = OldboyTeacher('egon', 16) # 调用类OldboyTeacher类得到类的对象obj

# 调用元类得到OldboyTeacher类(对象)问题又来了,class关键字是如何产生类的呢?

# class关键字底层做了哪些事

# 先拿到一个类名

class_name = 'Oldboy'

# 然后拿到类的父亲

class_bases = (object,)

# 再运行类体代码,将产生的名字放到名称空间中

class_dic = {}

class_body = """

school = 'oldboy'

def __init__(self,name,age):

self.name = name

self.age = age

def say(self):

print('>>>')

"""

exec(class_body,{},class_dic)

print(class_dic)

# 调用元类(传入类的三大要素:类名,基类,类的名称空间,得到一个元类的对象

# 然后将元类的对象赋值给变量名OldboyTeacher就是我们用class自定义的那个类)

OldboyTeacher = type(class_name,class_bases,class_dic)自定义元类只有继承了type类的类才是自定义的元类

class Mymeta(type):

pass#1>先拿到一个类名:'egon'

#2>然后拿到类的父亲:(object,)

#3>再运行类体代码,将产生的名字放到名称空间中{...}

#4>调用元类(传入类的三大要素:类名,基类,类的名称空间)

# 得到一个元类的对象,然后将元类的对象赋值给变量名

单例模式一个类被多次调用产生的多个对象,但是对象内的数据都是一样的,这样就额外占用了内存空间,解决这个问题的方式就称为类的单例模式

class MyQLE():

def __init__(self,name,age):

self.name = name

self.age = age

obj = MyQLE('egon',19)

obj2 = MyQLE('egon',19)

print(obj) # 两个对象数据一样,但是占用了两份内存空间

print(obj2)方式一:classmethod功能

import setting # 例如从一个文件中取出固定的值

class MyQLE():

__instance = None # 定义一个变量

def __init__(self,name,age):

self.name = name

self.age = age

@classmethod

def singleton(cls): # 写成类方法

if cls.__instance: # 调用的时候判断变量有值,直接返回已存在的值,不用二次调用产生新的

return cls.__instance

else:

cls.__instance = cls(setting.name,setting.age) # 如果没有,将类实例化得到对象并赋值,返回

return cls.__instance

obj2 = MyQLE.singleton()

print(obj2)

obj = MyQLE.singleton()

print(obj)方式二:使用元类

# 方式二 : 使用元类

import setting

class Mymeta(type):

__instance = None

def __init__(self,class_name,class_banses,class_dic):

self.__instance = object.__new__(self) #类的对象

self.__init__(self.__instance,setting.name,setting.age)

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

if args or kwargs:

obj = object.__new__(self)

self.__init__(obj,*args, **kwargs)

return obj

else:

return self.__instance

class MySQL(metaclass=Mymeta):

def __init__(self,name,age):

self.name = name

self.age = age

obj2 = MySQL()

obj3 = MySQL()

print(obj2)

print(obj3)方式三:使用装饰器

# 方式三: 使用装饰器

import setting

def outter(func):

_instance = func(setting.name,setting.age)

def wrapper(*args,**kwargs):

if args or kwargs:

return func(*args,**kwargs)

else:

return _instance

return wrapper

@outter

class MySQL:

def __init__(self,name,age):

self.name = name

self.age = age

obj1 = MySQL()

obj2 = MySQL()

print(obj2)

print(obj1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值