python高级编程之元类(第3部分结束)
# -*- coding: utf-8 -*-
# python:2.x
__author__ = 'Administrator'
#元编程
#new-style类带来了一种能力,通过2个特殊方法(__new__和__metaclass__)在运行时修改类和对象的定义
#__new__方法
#它是一上元构建程序,每次一个对象被factor类实例化时就调用它
#例如:
class A(object):
def __new__(cls,):
print '__new__'
return object.__new__(cls)#默认情况
def __init__(self):
print '__init__'
self.a=1
a=A()
"""
__new__
__init__
-------------
__new__方法必须返回一个类的实例,因此它可以在对象创建之前或者之后修改类,这对于确保对象构造程序不会被设置成一个不希望的状态,或者添加一个不能被构造程序删除初始化是有帮助的
例如,__init__在子类中不会隐式调用,所以__new__可以用来确定已经在整个类层次中完成了初始化工作,如下
"""
class aaI(A):pass
aaa=aaI()
"""
__new__
__init__
"""
class MM(A):
def __init__(self):
print 'MM class init'
super(MM,self).__init__()
self.b=2
ccc=MM()
"""
__new__
MM class init
__init__
"""
#例如,网络套接字或者数据库应该在__new__中而不是__init__中控制,因为它在类工作必须完成这个初始化以及必须被继承的时候通知我们,例如
from threading import Thread
class Op(Thread):
def __init__(self):
pass
#print Op()AssertionError: Thread.__init__() was not called
"""这实际上是通过方法之上的断言来完成的(assert self.__initialized),并且可以简化为__new__中单一调用,因为这个实例除此之外就没有什么
“避免令人头痛的链接初始化”
__new__是对于对象状态隐式初始化需要的回报,这经使得可以在比__init__更
低的层次上定义一个初始化,这个初始化问题是会被调用.
"""
#__metaclass__方法
#元类提供了在关对象通过其工厂方法(factory)在内在中创建时进行交互的能力,效果与__new__相似,只不过在类级别上运行,内建类型type是内建基本工厂,用来 生成指定的名称,基类以及包含其特性的映射任何类,如下:
def methio():
return
# klass=type('MyClass',(object),{'methion':methio})
# is1=klass()
# is1.methio()
#与类显式定义类似
class C(object):
def me(self):
return 12
ss=C()
print ss.me()#12
"""
有了这样的功能,可以在调用type之前或者之后与类创建交互,一个特殊的特性已经被创建以链接到一个定制工厂上
__metaclass__(在python3000中,其将被一个显式构造程序参数替代)可以被添加到一个类定义中,以与创建过程交互。它的特性必须被设置为:
1接受和type相同参数(一个类名,一组基类,一个特性映射)
2返回一个类对象
完成以上事件是类似下面使用那种无束缚函数(equip函数),还有另一个类对象上一个方法,只要满足1和2就可以了,如果类有一个空的docstring,那么描述符就被自动地添加到类中,如下面
"""
def eqiup(classname,tyoes,dicts):
if '__dict__'not in dicts:
dicts['__doc__']=Api()
return type(classname,tyoes,dicts)
class Myclass(object):
__metalcass__=eqiup
def alright(self):
'''the ok method'''
return 'ok'
ma=Myclass()
ma.__class__
ma.__class__.__dict__['__doc__']
ma.y=1
print ma.__doc__
"""
这个变化在其他地方可能不行,因为__doc__是内建基本元类type只读特性,但是元类使代码变得更加复杂,而且在将其用于工作所有类的类时,健壮性变的更差
对于修改可读写的特性或者添加新特性而言,可以避免使用元类,而采用更简单的基于动态修改类实例解决方法,这些修改更容易管理,因为它们不需要被组合到一个类中(地个类只能有一个元类)
,例如
"""
def a(klass):
c=[l for l in klass.__name__ if l.isupper()]
klass.contracted_name=''.join(c)
def b(klass):
def logger(func):
def w(*a,**k):
print 'logger'
return func(*a,**k)
return w
for e in dir(klass):
if e.startswith('_'):
continue
value=getattr(klass,e)
if not hasattr(value,'im_func'):
continue
setattr(klass,e,logger(value))
def en(klass,*e):
for e21 in e:
e21(klass)
class Ms(object):
def ok(self):
'''i rweturn ok'''
return 'lied'
en(Ms,a,b)
t=Ms()
t.ok()
#这是很强大的表现:可以动态的地在已经被实例化的类定义上创建许多不同的变化
#在任何情况下,记住,元类或者动态增加只是一个补丁,它可能会很快的使精心定义,清晰的类层次结构变得一团糟,使用以下情况
"""
在框架级别,一个行为在许多类中是强制的时候
当一个特殊的行为被添加到目的是不与诸如记录日志这样的类提供功能交互时
--------------
更多例子,可以看david mertz对元类编程的一个很好的介绍,网址为:
www.onlamp.com/pub/a/python/2003/04/17/metaclasses.html?page=1
"""
python高级编程之元类(第3部分结束)的更多相关文章
- python高级编程之(类级):子类内建类型
# -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' #类级 #在2.2中,提出了类型(type0与类(class)统一( ...
- python 面向对象编程 之 元类
元类是类的类,使我们自定义的类,即我们用class定义类本质就是元类,是类的模板 四步走: 一:控制class定义类的过程 1.先拿到类名 2.在拿到基类 3.执行类体代码,得到名称空间的dict 4 ...
- 第三章:Python高级编程-深入类和对象
第三章:Python高级编程-深入类和对象 Python3高级核心技术97讲 笔记 3.1 鸭子类型和多态 """ 当看到一直鸟走起来像鸭子.游泳起来像鸭子.叫起来像鸭子 ...
- python 面向对象进阶之元类metaclass
一:知识储备 exec exec:三个参数 参数一:字符串形式的命令 参数二:全局作用域(字典形式),如果不指定,默认为globals() 参数三:局部作用域(字典形式),如果不指定,默认为local ...
- python高级编程:有用的设计模式3
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#访问者:有助于将算法从数据结构中分离出来"&qu ...
- python高级编程:有用的设计模式1
# -*- coding: utf-8 -*-__author__ = 'Administrator'#python高级编程:有用的设计模式#设计械是可复用的,某种程序上它对软件设计中觉问题提供的语言 ...
- python高级编程技巧
由python高级编程处学习 http://blog.sina.com.cn/s/blog_a89e19440101fb28.html Python列表解析语法[]和生成 器()语法类似 [expr ...
- python高级编程之选择好名称:完
由于时间关系,python高级编程不在放在这边进行学习了,如果需要的朋友可以看下面的网盘进行下载 # # -*- coding: utf-8 -*- # # python:2.x # __author ...
- 神级程序员通过两句话带你完全掌握Python最难知识点——元类!
千万不要被所谓"元类是99%的python程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
随机推荐
- css布局详解(一)——盒模型
一.网页布局的几种情况 今天让我们总结一下在css布局的各种情况做一个总结,为我们以后布局网页时做一个参考. 先看一张图,这是去年cssConf大会时阿里的 @寒冬winter 老师放出来的: 如图所 ...
- IEquatable(T) interface in .Net
原文:http://weblogs.asp.net/pawanmishra/iequatable-t-interface-in-net 泛型方法: public static bool AreEqua ...
- 如何安装windows7系统
在XP时代,光驱对于我们而言仅仅是装系统用,不过在Win7发布之后,可以用U盘直接安装,省时省力. 首先在互联网下载UltraISO光盘映像文件制作/编辑/格式转换工具,(当然还有其它如WinIS ...
- iOS图片拉伸技巧—— resizableImageWithCapInsets
http://blog.csdn.net/chaoyuan899/article/details/19811889
- 5 输出的properties文件按照key进行排序
import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileNotFoundException; ...
- STL set容器添加结构体并排序
#include <iostream> #include <string> #include <cstring> //strcpy #include <cst ...
- c#中serialPort1_DataReceived串口接收事件处理
1.缓冲区不定字节读取(波特率很高也没问题) //Thread.sleep(1000);//处理事件这块可以加上延时确保不定数的数据可以全部收到缓冲后,才去读缓冲内容--单位:毫秒 byte[] da ...
- Mysql存储过程分析
为了搞明白为什么mysql的存储过程是高效的,我们需要理解mysql的执行流程是什么,当输入sql语句之后,mysql会先进行sql语句语法正确性检查,然后再进行编译,然后才执行,最后把结果返回.如下 ...
- 【转】linux之自建yum仓库
原链接:http://www.live-in.org/archives/1410.html 平时使用yum方式安装更新软件,可以自建一个yum源,同步官方更新源,这样如果本地有机器要升级的话就可以直接 ...
- Linux下安装并启动MongDB
1.下载MongoDB 下载链接: http://www.mongodb.org/downloads 2.解压下载的压缩包 tar -zxvf mongodb-linux-x86_64-3.2.8.t ...