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能拿到第一手的信息:

  1. 类名
  2. 父类集合
  3. 类成员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的更多相关文章

  1. Python魔法方法总结及注意事项

    1.何为魔法方法: Python中,一定要区分开函数和方法的含义: 1.函数:类外部定义的,跟类没有直接关系的:形式: def func(*argv): 2.方法:class内部定义的函数(对象的方法 ...

  2. python魔法方法:__getattr__,__setattr__,__getattribute__

    python魔法方法:__getattr__,__setattr__,__getattribute__ 难得有时间看看书....静下心来好好的看了看Python..其实他真的没有自己最开始想的那么简单 ...

  3. python魔法方法大全

    1.python魔法方法详解: python魔法方法是可以修改重载的,如果你的对象实现(重载)了这些方法中的某一个,那么这个方法就会在特殊的情况下被 Python 所调用,你可以定义自己想要的行为,而 ...

  4. python魔法函数__dict__和__getattr__的妙用

    python魔法函数__dict__和__getattr__的妙用 __dict__ __dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值. 既然__dict__是个字典那么我们就 ...

  5. python's metaclass

    [python's metaclass] 和objc中类似,metaclass用于创建一个类对象,但与objc不同的是,objc中每个类对象有各自不同的metaclass,而python中的metac ...

  6. python 魔法方法补充(__setattr__,__getattr__,__getattribute__)

    python 魔法方法补充 1 getattribute (print(ob.name) -- obj.func())当访问对象的属性或者是方法的时候触发 class F(object): def _ ...

  7. 1. Python 魔法方法

    Python 魔法方法 基础: 如果你想... 所以,你写... Python调用... 初始化一个实例 x = MyClass() x.__init__() 作为一个字符串的"官方&quo ...

  8. with上下文管理 python魔法方法

    with语法在Python里很常见, 主要的利好是使用代码更简洁. 常见的使用场景有: 1. 资源对象的获取与释放. 使用with可以简化try...finally ... 2. 在不修改函数代码的前 ...

  9. Python魔法缓存,以数字开始

    Python魔法缓存,以数字开始 众所周知,Python是弱类型的脚本语言,变量的定义是不用声明类型的. a = 1 Python所有数字的本质都是对象, 他们是不可改变的数据类型,这意味着改变数字数 ...

随机推荐

  1. Method not found : Void System.Data.Objects.ObjectContextOptions.set_UseConsistentNullReferenceBehavior(Boolean)

    找不到方法:“Void System.Data.Objects.ObjectContextOptions.set_UseConsistentNullReferenceBehavior(Boolean) ...

  2. MATLAB cvx 工具包使用

    一个例子 m = ; n = ; p = ; A = randn(m,n); b = randn(m,); C = randn(p,n); d = randn(p,); e = rand; cvx_b ...

  3. 解决 IE 6/7 中console对象兼容性问题

    话不多说,直接上代码 (function (){ //创建空console对象,避免JS报错 if(!window.console) window.console = {}; var console ...

  4. Scrum - BB项目日志

    这是第三个Scrum团队开发,也是我首次担任Scrum Master一职.所以需要掌握的流程还是很多,也会碰到各种问题,在此记录一下,希望对以后有所帮助. Day1: 开了一次kick-off mee ...

  5. Testng之使用@DataProvider注解做数据驱动【转】

    原文:http://www.jianshu.com/p/8e333a0ec42a 前两天学了一下@DataProvider,今天有时间总结一下.testng很强大,提供了很多注解,其中利用@DataP ...

  6. WLAN信道

  7. Django如何搭建服务器

    建立django站点: 新建Django项目,我这里是使用命令创建项目的. django-admin startproject HelloDjango  创建HelloDjango项目 然后进入到He ...

  8. dubbo分布式rpc框架用法

    dubbo是阿里巴巴开源的分布式服务框架,致力于提供高性能和透明化的rpc远程服务调用方案,以及soa服务治理方案,如果没有分布式需求,是不需要dubbo的,分布式环境dubbo的使用架构官方给出了一 ...

  9. Salesforce + AngularJS + Bootstrap

    也可以分成三步: 1. 添加css和js引用: <apex:stylesheet value="https://maxcdn.bootstrapcdn.com/bootstrap/3. ...

  10. Java IO4:字符编码

    前言 字符编码,这本不属于IO的内容,但字节流之后写的应该是字符流,既然是字符流,那就涉及一个"字符编码的"问题,考虑到字符编码不仅仅是在IO这块,Java中很多场景都涉及到这个概 ...