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程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
随机推荐
- js笔记01
js编写页面特效动态脚本类型的语言变量:存储数据(日常生活中的东西,比如电视,手机,电脑,出生年份...)语法: var obj=value; obj不能为数字开头,且区分大小写 value对应数据类 ...
- web项目跨域访问
1.同域相互访问 假设A.html 与 b.html domain都是localhost (同域) A.html中iframe 嵌入 B.html,name=myframe A.html有js fun ...
- Qt5官方demo解析集21——Extending QML - Adding Types Example
本系列全部文章能够在这里查看http://blog.csdn.net/cloud_castle/article/category/2123873 又是一个新的系列了,只是这个系列和我们之前的Chapt ...
- BGP
http://network.51cto.com/art/200912/172439.htm http://blog.sina.com.cn/s/blog_b457dde80101cyqr.html ...
- JavaScript学习笔记之 数组方法一 堆栈 和队列
数组的方法 以及 堆栈的操作的方法 JavaScript是一种弱类型语言,不像其它程序语言需要严格定义数据类型.在JavaScript中数组可以任意修改变动,这样也就出现了一个问题,如果边遍历数组边操 ...
- Hacker(25)----病毒攻防之认识病毒
Internet中,计算机病毒是威胁计算机安全的程序.对于计算机病毒,用户不仅需要掌握其基础知识,还要认识常见的病毒及简单病毒制作方法.无论病毒基础还是制作简单病毒,用户需要掌握防御病毒的有效措施和专 ...
- arc engine - ILayer.
ILayer ILayer接口是被图层(Layer)对象实现的,图层对象是用来在地图中显示空间信息. 注意,图层不含有空间数据,它只是获取数据的一个引用层而已.图层对象是一个抽象对象,它定 ...
- cxf的使用及安全校验-01创建简单的服务端接口
最近因为项目的需要,研究了一下webservice的使用: 这里以cxf2.7.0为例,大致介绍一下,也用于备份啦(张立胜) 大致介绍一下项目的情况:项目有maven管理,webservice调用的方 ...
- DataSource
数据库连接池原理:在内存中开辟一段存储空间用来存储多个Connection连接,避免频繁的创建Connection,从而提高效率.代码如下: package jcbc.ds.test1; import ...
- ZigZag-LeetCode
题目: The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows l ...