很多pythonic的代码都会用到内置方法,根据自己的经验,罗列一下自己知道的内置方法。

__getitem__ __setitem__ __delitem__

这三个方法是字典类的内置方法,分别对应于查找、设置、删除操作,以一个简单的例子说明:

class A(dict):
def __getitem__(self, key):
print '__getitem__'
return super(A, self).__getitem__(key) def __setitem__(self, key, value):
print '__setitem__'
return super(A, self).__setitem__(key, value) def __delitem__(self, key):
print '__delitem__'
return super(A, self).__delitem__(key) a = A()
a[1] = 1
b = a[1]
del a[1]
a.get(1)

上面的代码中a[1] = 1实际上调用的就是a.__setitem__(1, 1), a[1]调用的是a.__get__item__(1), del a[1]调用的是a.__setitem__(1)。需要注意的是,字典示例的get方法和__getitem__方法不存在调用关系,两者互不影响。

__getattribute__ __getattr__ __setattr__ __delattr__

__getattribute__和__getattr__都是从python对象示例中获取成员变量的方法,差别在于__getattribute__在任何时候都会调用,而__getattr__只有在__getattribute__执行完成之后并且没有找到成员变量的时候才会执行。__setattr__在给成员变量赋值的时候调用,__delattr__在回收成员变量的时候调用,一下面的例子说明:

class A(object):
x = [] def __getattribute__(self, name):
print '__getattribute__'
return super(A, self).__getattribute__(name) def __setattr__(self, key, value):
print '__setattr__'
return super(A, self).__setattr__(key, value) def __getattr__(self, item):
print '__getattr__' def __delattr__(self, item):
print '__delattr__'
return super(A, self).__delattr__(item) a = A()
a.x
a.y
b = getattr(a, 'x')
b = getattr(a, 'y')
a.x = 1
a.y = 1
setattr(a, 'x', 1)
setattr(a, 'y', 1)
del a.x
del a.y

因为x是a的成员变量,a.x会调用a.__getattribue__('x'),而y不是a的成员变量,在调用a.__getattribue__('y')之后还会调用a.__getattr__('y'),内置方法getattr也是按照此顺序调用,唯一的区别在于getattr在成员变量不存在的时候不会抛出异常,而是给一个默认值。a.x = 1setattr(a, 'x', 1)都会调用a.__setattr__('x', 1),如果原来的成员变量不存在,__setattr__会给实例增加一个成员变量,而不是抛出异常。

__call__

如果重载了__call__方法,则实例对象就可以像方法一样调用了。如果实例a的类实现了这个方法,那么a(*args, **kwargs)就会调用a.__call__(*args, **kwargs)。用这种方法可以简单方便的实现装饰器,如下所示:

class A(object):
def __init__(self, func):
self.func = func def __call__(self, *args, **kwargs):
print '__call__'
return self.func(*args, **kwargs) @A
def foo(x):
return x foo(1)

装饰器语法糖相当于foo = A(foo), 和闭包不同,foo已经不是一个函数而是类A的实例。foo(1)会执行foo.__call__(1)。当然这个例子实现的装饰器并不好,会改变foo的函数签名,而且也不能装饰类方法。

此外元类的__call__也可以控制实例的创建过程,因为当类创建对象时,元类的__call__函数就被调用,进而调用type.__call__创建对象,type.__call__回依次调用类的__new__和__init__生成实例。以单例模式为例:

class Singleton(type):
def __call__(cls, *args):
print "Singleton call"
if not hasattr(cls, 'instance'):
cls.instance = super(Singleton, cls).__call__(*args)
return cls.instance class Cache(object): __metaclass__ = Singleton def __new__(cls, *args):
print "Cache new"
return object.__new__(cls, *args) def __init__(cls, *args, **kwargs):
print "Cache init" a = Cache()
b = Cache()
print a is b

__get__ __set__

这三个方法分别对应于描述器的查询、设置、删除函数,还是以一个简单的例子来说明:

class A(object):

    def __get__(self, instance, owner):
print '__get__' def __set__(self, instance, value):
print '__set__' class B(object):
a = A() b = B()
c = b.a
b.a = 1

类A的示例a作为b的成员变量时候,访问示例b中成员变量a的时候会调用a.__get__(b, B),修改b中成员变量a的时候会调用a.__set__(b, 1)。需要注意的是,当用B.a访问的时候参数instance为None。实际上像classmethod,staticmethod这样的装饰器都是通过装饰器来实现的,通过装饰器就可以解决上面不能作为类方法装饰器的问题。

import types

class Profiled(object):
def __init__(self, func):
self.func = func def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs) def __get__(self, instance, owner):
if instance is None:
return self
else:
return types.MethodType(self, instance) class Spam(object):
@Profiled
def bar(self, x):
return x + 1 s = Spam()
print s.bar(5)

在__get__方法中,不是Spam.bar调用,则instance不为None的情况下,会用types.MethodType把bar和s做一个绑定,s.bar(5)等价于执行了bar.__get__(s, Spam).__call__(5),看起来很绕,但实际上用起来很方便。

python黑魔法 -- 内置方法使用的更多相关文章

  1. python 字典内置方法get应用

    python字典内置方法get应用,如果我们需要获取字典值的话,我们有两种方法,一个是通过dict['key'],另外一个就是dict.get()方法. 今天给大家分享的就是字典的get()方法. 这 ...

  2. Python的内置方法,abs,all,any,basestring,bin,bool,bytearray,callable,chr,cmp,complex,divmod

    Python的内置方法 abs(X):返回一个数的绝对值,X可以是一个整数,长整型,或者浮点数,如果X是一个复数,此方法返回此复数的绝对值(此复数与它的共轭复数的乘积的平方根) >>> ...

  3. 7.python字符串-内置方法分析

    上篇对python中的字符串内置方法进行了列举和简单说明,但这些方法太多,逐一背下效率实在太低,下面我来对这些方法按照其功能进行总结: 1.字母大小写相关(中文无效) 1.1 S.upper() -& ...

  4. 6.python字符串-内置方法列举

    所谓内置方法,就是凡是字符串都能用的方法,这个方法在创建字符串的类中,下面是总结: 首先,我们要学习一个获取帮助的内置函数 help(对象) ,对象可以是一个我们创建出来的,也可以是创建对象的那个类, ...

  5. python字符串-内置方法列举

    所谓内置方法,就是凡是字符串都能用的方法,这个方法在创建字符串的类中,下面是总结: 首先,我们要学习一个获取帮助的内置函数 help(对象) ,对象可以是一个我们创建出来的,也可以是创建对象的那个类, ...

  6. python字符串内置方法

    网上已经有很多,自己操作一遍,加深印象. dir dir会返回一个内置方法与属性列表,用字符串'a,b,cdefg'测试一下 dir('a,b,cdefg') 得到一个列表 ['__add__', ' ...

  7. Python的内置方法

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象 class Foo(object) ...

  8. Python字典内置方法

    Python字典包含了以下内置方法: 序号 函数及描述 1 radiansdict.clear()删除字典内所有元素 2 radiansdict.copy()返回一个字典的浅复制 3 radiansd ...

  9. python数据类型内置方法

    内容概要 列表内置方法 字典内置方法 字符串转换成字典的方法 eval() 元组内置方法 元组相关笔试题 集合内置方法 列表内置方法 l1 = [2, 4, 5, 7, 3, 9, 0, 6] # 升 ...

随机推荐

  1. 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代

    2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...

  2. Python标准库--typing

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 Python 3.5 增加了一个有意思的库--typ ...

  3. CRL快速开发框架系列教程十(导出对象结构)

    本系列目录 CRL快速开发框架系列教程一(Code First数据表不需再关心) CRL快速开发框架系列教程二(基于Lambda表达式查询) CRL快速开发框架系列教程三(更新数据) CRL快速开发框 ...

  4. 【绝对干货】仿微信QQ设置图形头像裁剪,让你的App从此炫起来~

    最近在做毕业设计,想有一个功能和QQ一样可以裁剪头像并设置圆形头像,额,这是设计狮的一种潮流. 而纵观现在主流的APP,只要有用户系统这个功能,这个需求一般都是在(bu)劫(de)难(bu)逃(xue ...

  5. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  6. C# 给word文档添加水印

    和PDF一样,在word中,水印也分为图片水印和文本水印,给文档添加图片水印可以使文档变得更为美观,更具有吸引力.文本水印则可以保护文档,提醒别人该文档是受版权保护的,不能随意抄袭.前面我分享了如何给 ...

  7. Boost信号/槽signals2

    信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...

  8. Maven常用命令

    开发中常用的命令: 1. mvn compile 编译源代码2. mvn test-compile 编译测试代码3. mvn test 运行测试4. mvn package 打包,根据pom.xml打 ...

  9. 「译」JUnit 5 系列:环境搭建

    原文地址:http://blog.codefx.org/libraries/junit-5-setup/ 原文日期:15, Feb, 2016 译文首发:Linesh 的博客:环境搭建 我的 Gith ...

  10. 一条Sql语句分组排序并且限制显示的数据条数

    如果我想得到这样一个结果集:分组排序,并且每组限定记录集的数量,用一条SQL语句能办到吗? 比如说,我想找出学生期末考试中,每科的前3名,并按成绩排序,只用一条SQL语句,该怎么写? 表[TScore ...