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程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
随机推荐
- Ruby中,类方法和实例方法的一个有趣的例子
最初的代码如下: class Object def abc p "instance abc" end def self.abc p "class abc" en ...
- (转) [老老实实学WCF] 第三篇 在IIS中寄存服务
第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我们对WCF的编程生 ...
- 网站飘窗js代码
<SCRIPT> var imagepath="/${res}/images/geren.jpg" ; var imagewidth=178 ;//这两行写图片的大小 ...
- linux删除ORACLE【weber出品必属精品】
关闭数据库 sqlplus / as sysdba shutdown abort 清除oracle软件 su - oracle cd $ORACLE_BASE rm -rf * rm -rf /etc ...
- iOS_SN_沙盒文件操作及位置
转载:http://blog.csdn.net/hello_hwc/article/details/44916909 沙盒的结构如下所示 一 访问Bundle 注意Bundle只读,不能写入 创建一个 ...
- C#调用进程
Process process = new Process(); process.StartInfo.FileName = "123.exe"; process.StartInfo ...
- 8 fastJson的使用
Fastjson介绍 Fastjson是一个Java语言编写的JSON处理器,由阿里巴巴公司开发. 1.遵循http://json.org标准,为其官方网站收录的参考实现之一. 2.功能qiang打, ...
- C/C++中define的使用
代码: #include <iostream> using namespace std; #define a 10 void foo(); void bar(); void foo(){ ...
- [C入门 - 游戏编程系列] 贪吃蛇篇(三) - 蛇定义
蛇是这个游戏的主角,要实现的功能也是最复杂的一个.因为蛇不止有属性,还有行为.它会动,还会吃东西,还会长大!而且还会死!这是很要命的.我一向看不懂复杂的代码,也写不出复杂的代码.所以对于蛇,我很纠结, ...
- 根据identifier从StoryBoard中获取对象,UIButton的图片文件位置
@import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...