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程序员不会用到的特性"这类的说辞吓住.因为 每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生 ...
随机推荐
- Vagrant入门[转]
Vagrant是一个简单易用的部署工具,用英文说应该是orchestration tool.它能帮助开发人员迅速的构建一个开发环境,帮助测试人员构建测试环境. Vagrant的基本工作原理大致如下: ...
- [Regular Expressions] Find Repeated Patterns
Regular Expression Quantifiers allow us to identify a repeating sequence of characters of minimum an ...
- UITableView的简单总结与回顾
今天突发奇想的想对UItableView做一下汇总,感觉在编程中这个控件可以千变万化也是用的最多的一个了,下面就为大家简单总结下这个控件,也许还有不足,不过还是请各位不吝赐教了哈,那么我就开始了,我会 ...
- JS高级程序设计学习笔记之JS事件(1)
事件流 冒泡 定义:事件开始时由最具体的元素接收,然后逐级上传到较为不具体的节点.(IE9.FF.Chrome.Safari会将事件一直冒泡到window对象.IE5.5及其以下会跳过<html ...
- SqlServer表属性查询
获得表信息: select syscolumns.name as field, syscolumns.isnullable as nullis, systypes.name as sqltype, s ...
- ASP.Net MVC与WebForm的区别
- How to resolve the SQL error “cannot connect to WMI provider”
当你试图打开SQL Server Configuation Manager时发现如下错误: “cannot connect to WMI provider. You do not have permi ...
- java文件读写的两种方式
今天搞了下java文件的读写,自己也总结了一下,但是不全,只有两种方式,先直接看代码: public static void main(String[] args) throws IOExceptio ...
- 点击推送消息跳转处理(iOS)
当用户点击收到的推送消息时候,我希望打开APP,并且跳转到对应的界面,这就需要在AppDelegate里面对代理方法进行处理. 当用户点击推送消息打开APP的时候会调用 - (BOOL)applica ...
- JS常用验证方法
1.验证必须为数字(可有小数点) if(isNaN(value))execCommand('undo') 说明:1.isNaN()方法用于验证value值是否为非法数字,返回值true或者false. ...