Python魔法 - MetaClass
Python魔法 - MetaClass
metaclass
The class of a class. Class definitions create a class name, a class dictionary, and a list of base classes. The metaclass is responsible for taking those three arguments and creating the class. Most object oriented programming languages provide a default implementation. What makes Python special is that it is possible to create custom metaclasses. Most users never need this tool, but when the need arises, metaclasses can provide powerful, elegant solutions. They have been used for logging attribute access, adding thread-safety, tracking object creation, implementing singletons, and many other tasks.
metaclass是class的class,类的类 - 元类,那肯定最累了,所有实例的创建都需要metaclass的参与. metaclass能拿到第一手的信息:
- 类名
- 父类集合
- 类成员dict
然后想怎么改就怎么改,这就是当你看到某些class明明定义了xxx,可是运行时总是报错:没有xxx。
metaclass允许你创建类或者修改类。换句话说,你可以把类看成是metaclass创建出来的“实例”,没有它你的calss也会抛未定义错误。
使用metaclass来为类添加方法
通过修改metacalss,是创建的实例默认就有某些方法,这样是不是装逼过度?直接修改来的属性不就搞定了么.是的,但是总有些场景需要这么做。这里我们只能那个不是很实用的场景来看看metaclass是如何修改类的。
按照默认习惯,metaclass的类名总是以Metaclass结尾,以便清楚地表示这是一个metaclass.
*. 任务:
1. 给PythonProgrammer类添加一个play_cool method
2. 去掉PythonProgrammer类的has_girlfriend, 好悲催
class ProgrammerMetaClass(type):
"""docstring for Programmer"""
def __new__(cls, name, bases, attrs):
# 这里可以对类胡作非为的修改
# 1.添加 play_cool method
attrs['play_cool'] = lambda self: print('Programmers are cool...')
# 2.删除属性
if 'has_girlfriend' in attrs:
del attrs['has_girlfriend']
return type.__new__(cls, name, bases, attrs)
class PythonProgrammer(object, metaclass=ProgrammerMetaClass):
"""docstring for PythonProgrammer"""
has_girlfriend = 0
def __init__(self, language):
super(PythonProgrammer, self).__init__()
self.language = language
pp = PythonProgrammer('python')
pp.play_cool()
# Programmers are cool...
print(pp.has_girlfriend)
Traceback (most recent call last):
File "D:\GitHub\learn_python\temp.py", line 78, in <module>
print(pp.has_girlfriend)
AttributeError: 'PythonProgrammer' object has no attribute 'has_girlfriend'
print(PythonProgrammer.has_girlfriend)
Traceback (most recent call last):
File "D:\GitHub\learn_python\temp.py", line 79, in <module>
print(PythonProgrammer.has_girlfriend)
AttributeError: type object 'PythonProgrammer' has no attribute 'has_girlfriend'
Python魔法 - MetaClass的更多相关文章
- Python魔法方法总结及注意事项
1.何为魔法方法: Python中,一定要区分开函数和方法的含义: 1.函数:类外部定义的,跟类没有直接关系的:形式: def func(*argv): 2.方法:class内部定义的函数(对象的方法 ...
- python魔法方法:__getattr__,__setattr__,__getattribute__
python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...
- python魔法方法大全
1.python魔法方法详解: python魔法方法是可以修改重载的,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而 ...
- python魔法函数__dict__和__getattr__的妙用
python魔法函数__dict__和__getattr__的妙用 __dict__ __dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值. 既然__dict__是个字典那么我们就 ...
- python's metaclass
[python's metaclass] 和objc中类似,metaclass用于创建一个类对象,但与objc不同的是,objc中每个类对象有各自不同的metaclass,而python中的metac ...
- python 魔法方法补充(__setattr__,__getattr__,__getattribute__)
python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...
- 1. Python 魔法方法
Python 魔法方法 基础: 如果你想... 所以,你写... Python调用... 初始化一个实例 x = MyClass() x.__init__() 作为一个字符串的"官方&quo ...
- with上下文管理 python魔法方法
with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...
- Python魔法缓存,以数字开始
Python魔法缓存,以数字开始 众所周知,Python是弱类型的脚本语言,变量的定义是不用声明类型的. a = 1 Python所有数字的本质都是对象, 他们是不可改变的数据类型,这意味着改变数字数 ...
随机推荐
- Nginx开启Gzip压缩
.Vim打开Nginx配置文件 vim /usr/local/nginx/conf/nginx.conf .找到如下一段,进行修改 gzip on; gzip_min_length 1k; gzip_ ...
- JDBC学习笔记(2)
上一篇博客简单介绍了JDBC连接的简单知识,下面就详细介绍.李勇老师对JDBC连接有很好的比喻: 首先加载驱动,其实就是一些类,就是jar包,要加载到classpath里面的.实际的程序,服务和数据库 ...
- 积木大赛 noip2013提高组day2
这道题一开始想到处理中间是0的位置,但这样时间太慢了,后来想到一种类似二分的方法,就是把这一段的最小值找到,全部减去最小值,然后有0一出现,就又递归处理前一段,每次答案就加上这一段的最小值: AC代码 ...
- 特征哈希(Feature Hashing)
[本文链接:http://www.cnblogs.com/breezedeus/p/4114686.html,转载请注明出处] 我的博客主营地迁至github,欢迎朋友们有空去看看:http://br ...
- ruby使用DBI连接MySQL数据库发生异常:in `error': Can't connect to MySQL server on 'localhost' (10061) (DBI::DatabaseError)
Ruby使用DBI连接MySQL数据库一般为: require "dbi" dbh = DBI.connect("dbi:Mysql:test:localhost&quo ...
- 基于VC的ACM音频编程接口压缩Wave音频(二)
(二)获取CODECs 的 信 息 ACM 的API 函 数 定 义 在 头 文 件msacm.h 中, 除 此 之 外, 对ACM 编 程 还 必 须 包 含 头 文 件mmsystem.h,mm ...
- mongoDB研究笔记:分片集群部署
前面几篇文章的分析复制集解决了数据库的备份与自动故障转移,但是围绕数据库的业务中当前还有两个方面的问题变得越来越重要.一是海量数据如何存储?二是如何高效的读写海量数据?尽管复制集也可以实现读写分析,如 ...
- 一、ASP.NET MVC 路由(一)--- ASP.NET WebForm路由模拟
ASP.NET WebForm 应用,用户请求的是物理文件,其中包括静态页面和动态页面,在Url中的显示都是服务器中一个物理文件的相对路径.但是ASP.NET MVC就不同了,用户请求的是Contro ...
- 【腾讯Bugly干货分享】iOS10 SiriKit QQ适配详解
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57ece0331288fb4d31137da6 1. 概述 苹果在iOS10开放 ...
- Backbone源码解析(一):Event模块
Backbone是一个当下比较流行的MVC框架.它主要分为以下几个模块: Events, View, Model, Collection, History, Router等几大模块.它强制依赖unde ...