python 之 面向对象(元类、__call__、单例模式…
2019-07-24 09:17:43来源:博客园 阅读 ()
7.13 元类
元类:类的类就是元类,我们用class定义的类来产生我们自己的对象的,内置元类type是用来专门产生class定义的类
code=""" global x x=0 y=2 """ #字符串内声明的名称是全局,其他为局部名称 global_dic={'x':100000} local_dic={} # 运行字符串内代码 exec(code,global_dic,local_dic) # 把全局名称空间的名称放入global_dic,把局部的放入local_dic ? print(global_dic) #{'x': 0} print(local_dic) #{'y': 2}
7.131 用内置的元类type,来实例化得到我们的类
class_name='Chinese' class_bases=(object,) #基类 class_body=""" country="China" def __init__(self,name,age,sex): self.name=name self.age=age self.sex=sex def speak(self): print('%s speak Chinese' %self.name) """ class_dic={} exec(class_body,{},class_dic) ? # 类的三大要素 print(class_name,class_bases,class_dic) # Chinese (<class 'object'>,) {'country':'China', '__init__': <function __init__ at ...>, 'speak': <function speak at....>} ? Chinese=type(class_name,class_bases,class_dic) #实例化一个类 print(Chinese) #<class '__main__.Chinese'> ? p=Chinese('egon',18,'male') #实例化对象p print(p.name,p.age,p.sex) # egon 18 male #说明和class定义的类功能相同
7.132 __call__
方法
在调用对象时自动触发__call__
的执行
class Foo: def __init__(self): pass ? def __call__(self, *args, **kwargs):# 调用对象,则会自动触发对象下的绑定方法__call__的执行, print('__call__',*args, **kwargs)# 然后将对象本身当作第一个参数传给self,将调用对象时括号内的值传给*args与**kwargs obj=Foo() obj(1,2,3,a=1,b=2,c=3) #对象调用
7.133 自定义元类来控制类的创建行为
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #self=Foo print(class_name) print(class_bases) print(class_dic) if not class_name.istitle(): #控制类名首字母必须大写 raise TypeError('类名的首字母必须大写傻叉') ? if not class_dic.get('__doc__'): # 控制文档注释必须存在 raise TypeError('类中必须写好文档注释,大傻叉') ? super(Mymeta,self).__init__(class_name,class_bases,class_dic) #重用父类功能 #Foo=Mymeta('Foo',(object,),class_dic) class Foo(object,metaclass=Mymeta): # metaclass=Mymeta创建自定义元类 """ 文档注释 """
7.134 自定义元类来控制类的调用
控制类Foo的调用过程,即控制实例化Foo的过程
class Mymeta(type): def __init__(self,class_name,class_bases,class_dic): #self=Foo print(class_name) print(class_bases) print(class_dic) def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={} #1 造一个空对象obj obj=object.__new__(self) ? #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__ self.__init__(obj,*args,**kwargs) return obj #Foo=Mymeta('Foo',(object,),class_dic) class Foo(object,metaclass=Mymeta): x=1 def __init__(self,y): self.y=y ? def f1(self): print('from f1') obj=Foo(1111) #Foo.__call__() print(obj) #<__main__.Foo object at 0x000002019EE1BB70> print(obj.y) # 1111 print(obj.f1) #<bound method Foo.f1 of <__main__.Foo object at 0x000002019EE1BB70>> print(obj.x) # 1
7.14 单例模式
对于对象通过相同的配置文件进行实例化,可以使几个对象使用同一个内存地址,节省内存
import settings class MySQL: __instance=None def __init__(self,ip,port): self.ip=ip self.port=port ? @classmethod def singleton(cls): if not cls.__instance: obj=cls(settings.IP, settings.PORT) cls.__instance=obj return cls.__instance ? obj1=MySQL('1.1.1.2',3306) obj2=MySQL('1.1.1.3',3307) obj3=MySQL('1.1.1.4',3308) ? obj4=MySQL.singleton() # obj4=MySQL(settings.IP,settings.PORT) obj5=MySQL.singleton() obj6=MySQL.singleton() print(obj4.ip,obj4.port) # 1.1.1.1 3306 ? print(obj4 is obj5 is obj6) # True
原文链接:https://www.cnblogs.com/mylu/p/11160439.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:企查查app新增企业数据抓取
- python3基础之“术语表(2)” 2019-08-13
- python3 之 字符串编码小结(Unicode、utf-8、gbk、gb2312等 2019-08-13
- Python3安装impala 2019-08-13
- 小白如何入门 Python 爬虫? 2019-08-13
- python_字符串方法 2019-08-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash