文档章节

python 元类编程

charlesdong1989
 charlesdong1989
发布于 2014/05/14 12:28
字数 735
阅读 326
收藏 2

##基础知识:## Python Class 对象或类型通过内置成员 dict 来存储成员信息。
还可以通过重载 getattrsetattr 来拦截对成员的访问,需要注意的是 getattr 只有在访问不存在的成员时才会被调用。
如果类型继承自 object,我们可以使用 getattribute 来拦截所有(包括不存在的成员)的获取操作

dict 返回类的属性字典, 会调用__getattrbute__
如果有一个类A;
a = A()
a.dict 和 A.__dict__会有所不同, a__dict__中没有方法,而 A.dict 有方法。
所以可见 类方法是类的属性被所有对像共享。

python的对象可以动态加属性,例如  a.ss=3, 这时a.__dict__就会有ss的key, 而A.__dict__ 不会有这个key,从而引申出类属性和对象属性(这里不做过多解释)。

这里要问一个问题了:
对象的__dict__中没有方法, 那对象是怎么调用方法的呢?
在这里就引申出Descriptor个东西:

class RevealAccess(object):
    def __init__(self, initval=None, name='var'):
        self.val = initval
        self.name = name

    def __get__(self, obj, objtype):
        print 'Retrieving', self.name
        return self.val

    def __set__(self, obj, val):
        print 'Updating' , self.name
        self.val = val

在类中定义__get__和__set__方法的,成为descriptor
它是用来做什么的呢。。。。。
再写一个类:

class MyClass(object):
    x = RevealAccess(10, 'var "x"')

    def __init__(self):
        self.y = 5

    def test(self):
        print 'hello world!'
    test = RevealAccess(test, 'var "x"')

if __name__ == "__main__":
    m = MyClass()
    print m.y
    # 输出
    # 5
    print m.x     
    # 输出
    # Retrieving var "x"
    # 10
    print m.test
    # 输出
    # Retrieving var "x"
    # <function test at 0x02CBE870>

哈哈, 结果看出来了吧;当对像调用x(属性),test(方法)的时候都调用了__get__方法。 这个RevealAccess的对象就是一个descriptor。访问属性m.x就是调用__get__方法,设置属性值就是调用__set__方法。还可以有一个__delete__方法,在del m.x时被调用。

下一个问题:
print MyClass.dict["test"] # 输出: <function test at 0x02C9E8F0> print m.test # 输出: <bound method MyClass.test of <main.MyClass object at 0x02C9DB70>> 这是什么情况, 这俩明显不是一个东西, 什么情况。
这说明test方法在类中仅仅是一个function, 他跟对象还是没关系。 print MyClass.dict["test"].get(m, Myclass) # 输出: <bound method MyClass.test of <main.MyClass object at 0x02CDDB90>> 这回是一个东西了,其实,类的成员函数就是一个descriptor,在实例化对象m的时候,做了m.test = MyClass.dict["test"].get(m, Myclass) 这么一件事,这回通了。哈哈。

有了这个基础: 理解一下staticmethod和classmethod这两个decorator,staticmethod就是像RevealAccess一样忽略第一个参数,直接返回参数。classmethod就是手动赛一个对像进去: def get(self, obj, klass=None): if klass is None: klass = type(obj) def newfunc(*args): return self.f(klass, *args) return newfunc

dict 妙用
<!-- lang: python --> class Person: def init(self,_obj): self.name = _obj['name'] self.age = _obj['age'] self.energy = _obj['energy'] .............. class Person: def init(self, _obj): self.dict.update(_obj) 这样就减少了很多代码量
delattr: 当使用 p = Person(); del p.name 会调用

主要参考http://hbprotoss.github.io/posts/python-descriptor.html http://blog.jobbole.com/21351/

© 著作权归作者所有

charlesdong1989
粉丝 22
博文 155
码字总数 84903
作品 0
海淀
私信 提问
深刻理解Python中的元类(metaclass)

深刻理解Python中的元类(metaclass) 译注:这是一篇在Stack overflow上很热的帖子。提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解。他知道这肯定...

memorybox
2013/05/05
317
0
深刻理解Python中的元类

译注:这是一篇在Stack overflow上很热的帖子。提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解。他知道这肯定和自省有关,但仍然觉得不太明白,希...

ifnoelse
2014/07/21
92
0
Python高级编程和异步IO并发编程

Python高级编程和异步IO并发编程 网盘地址:https://pan.baidu.com/s/1eB-BsUacBRhKxh7qXwndMQ 密码: tgba 备用地址(腾讯微云):https://share.weiyun.com/5Z3x9V0 密码:7cdnb2 针对Pytho...

人气王子333
2018/04/23
0
0
OpenERP与Python 元编程

Python元编程被称为“黑魔法”。Python界的传奇人物Tim Peters有云: 引用 Python的元编程这种黑魔法99%的人都无需了解,如果你拿不准是否应该用到它时,你不需要它. OpenERP基本遵循了Tim P...

TomChin
2013/10/08
128
0
面试时全对这25道python面试题,成就了我月薪20K!

之前面试的时候,面试官拿出一些python面试题对我说,只要全部正确直接给我20K,我一看题目笑了,居然全部都会,今天拿出来给大家分享一下~ 先给大家介绍一下python Python 是一种解释型,交...

Python小老弟
03/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
7
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
7
0
Flutter系列之在 macOS 上安装和配置 Flutter 开发环境

本文为Flutter开发环境在macOS下安装全过程: 一、系统配置要求 想要安装并运行 Flutter,你的开发环境需要最低满足以下要求: 操作系统:macOS(64位) 磁盘空间:700 MB(不包含 IDE 或其余...

過愙
昨天
6
0
OSChina 周六乱弹 —— 早上儿子问我他是怎么来的

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @凉小生 :#今日歌曲推荐# 少点戾气,愿你和这个世界温柔以待。中岛美嘉的单曲《僕が死のうと思ったのは (曾经我也想过一了百了)》 《僕が死の...

小小编辑
昨天
2.7K
16
Excption与Error包结构,OOM 你遇到过哪些情况,SOF 你遇到过哪些情况

Throwable 是 Java 中所有错误与异常的超类,Throwable 包含两个子类,Error 与 Exception 。用于指示发生了异常情况。 Java 抛出的 Throwable 可以分成三种类型。 被检查异常(checked Exc...

Garphy
昨天
42
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部