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所有数字的本质都是对象, 他们是不可改变的数据类型,这意味着改变数字数 ...
随机推荐
- eclipse js 引用跳转
引用 http://stackoverflow.com/questions/24505993/the-resource-is-not-on-the-build-path-of-a-javascript ...
- python学习粘贴
1. Python通过re模块提供对正则表达式的支持.使用re的一般步骤是先使用re.compile()函数,将正则表达式的字符串形式编译为Pattern实例,然后使用Pattern实例处理文本并获得 ...
- XAF 官方问题笔记
1.How to print report direct, and print preview via an simple action? 如何通过一个按钮直接打印报表或者打印预览报表 https:/ ...
- code review
代码审核,开发者代码完工,就可以下一个环节,即代码审核,通过代码审核,可以看到多个开发者的代码规范,隐藏的BUG,一些注释等规范. 通过代码审核,我们开发者可以互相学习,使得代码逻辑正确,重用
- eclipse执行上一次结果
eclipse执行上一次结果,解决方法:Project-clean
- vim 配置
backspace有几种工作方式,默认是vi兼容的.对新手来说很不习惯.对老vi 不那么熟悉的人也都挺困扰的.可以用set backspace=indent,eol,start来解决. indent: ...
- PHP中实现MySQL嵌套事务的两种解决方案
PHP中实现MySQL嵌套事务的两种解决方案 一.问题起源 在MySQL的官方文档中有明确的说明不支持嵌套事务: Transactions cannot be nested. This is a co ...
- JSON 序列化和反序列化——JavaScriptSerializer实现
一. JavaScriptSerializer 类由异步通信层内部使用,用于序列化和反序列化在浏览器和 Web 服务器之间传递的数据.您无法访问序列化程序的此实例.但是,此类公开了公共 API.因此, ...
- mongoDB研究笔记:复制集概述
自我学习,仅供参考: 数据库总是会遇到各种失败的场景,如网络连接断开.断电等,尽管journaling日志功能也提供了数据恢复的功能,但journaling通常是针对单个节点来说的,只能保证单节点数据 ...
- SQL入门经典(十) 之事务
事务是什么?事务关键在与其原子性.原子性概念是指可以把一些事情当作一个执行单元来看待.从数据库角度看待.他是指应该全部执行或者全部不执行一条或多条语句的最小组合.当处理数据时候经常确保一件事发生另一件 ...