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程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
随机推荐
- pyqt cvs保存
# -*- coding: utf-8 -*-__author__ = 'Administrator'import sys, csvfrom PyQt4 import QtGui, QtCore cl ...
- Hibernate中Criteria的用法
概念 Criterion 是 Criteria 的查询条件.Criteria 提供了 add(Criterion criterion) 方法来添加查询条件. Criterion 接口的主要实现包括: ...
- EBS OAF开发中的Java 实体对象(Entity Object)验证功能补充
EBS OAF开发中的Java 实体对象(Entity Object)验证功能补充 (版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) EO理论上 ...
- Linux基本操作 1-----命令行BASH的基本操作
1 Shell(壳)是用户与操作系统底层(通常是内核)之间交互的中介程序,负责将用户指令.操作传递给操作系统底层 shell 分为两种 CUI : Command Line Interface Lin ...
- SQL中@@ROWCOUNT函数
返回受上一语句影响的行数.如果行数大于 20 亿,请使用 ROWCOUNT_BIG. 语法 @@ROWCOUNT 返回类型 int 注释 Transact-SQL 语句可以通过下列方 ...
- AndroidAnnotations框架配置
如今Android Studio的普及,Android开发基本要舍弃Eclipse了,最近使用AndroidAnnotations 注解框架的时候,找了些资料慢慢整出来了,在这给大家简单分享一下: 首 ...
- unity碰撞组件、刚体组件
游戏导入标准资源包“Character Controllers”后可以为游戏对象添加 character(角色控制器)组件: 添加角色控制器组建以后可以控制游戏对象移动: 角色控制器组件因为与碰撞组件 ...
- ADO.NET DataReader和DataAdapter的区别
SqlDataReader是一个向前的指针,本身并不包含数据,调用一次 Read() 方法它就向前到下一条记录,一个SqlDataReader必须单独占用一个打开的数据库连接. 在使用 SqlData ...
- Web C# 导出Excel 方法总结
方法1:微软推荐服务器需安装Excel型 依赖: 软件:Office Excel 2007-2013 引用:Microsoft Office 14.0 Object Library 1.1 数据准备 ...
- (三)原生JS实现 - 插件 - 弹出层
创建遮罩层 _createCover: function() { var newMask = document.createElement("div"); newMask.id = ...