很多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. 详解树莓派Model B+控制蜂鸣器演奏乐曲

    步进电机以及无源蜂鸣器这些都需要脉冲信号才能够驱动,这里将用GPIO的PWM接口驱动无源蜂鸣器弹奏乐曲,本文基于树莓派Mode B+,其他版本树莓派实现时需参照相关资料进行修改! 1 预备知识 1.1 ...

  2. .NET Core系列 :4 测试

    2016.6.27 微软已经正式发布了.NET Core 1.0 RTM,但是工具链还是预览版,同样的大量的开源测试库也都是至少发布了Alpha测试版支持.NET Core, 这篇文章 The Sta ...

  3. Asp.net MVC 传递数据 从前台到后台,包括单个对象,多个对象,集合

    今天为大家分享下 Asp.net MVC 将数据从前台传递到后台的几种方式. 环境:VS2013,MVC5.0框架 1.基本数据类型 我们常见有传递 int, string, bool, double ...

  4. 旺财速啃H5框架之Bootstrap(二)

    突然感觉不知道写啥子,脑子里面没水了,可能是因为今晚要出去浪,哈哈~~~提前提醒大家平安夜要回家哦,圣诞节生00000000000这么多蛋....继续 上一篇的已经把bootstrap了解个大概了,接 ...

  5. 和 Thrift 的一场美丽邂逅

    一. 与 Thrift 的初识 也许大多数人接触 Thrift 是从序列化开始的.每次搜索 “java序列化” + “方式”.“对比” 或 “性能” 等关键字时,搜索引擎总是会返回一大堆有关各种序列化 ...

  6. mybatis_个人总结

    在使用mybatis框架开发数据访问层的过程中,我在这段时间遇到很多细节问题困住我,在这里我来分享一下我遇到的坑,希望能帮到大家. 一.mybatis动态代理方式开发的规范: 1.注意在mybatis ...

  7. Linux之搭建自己的根文件系统

    Hi!大家好,我是CrazyCatJack.又和大家见面了.今天给大家带来的是构建Linux下的根文件系统.希望大家看过之后都能构建出符合自己需求的根文件系统^_^ 1.内容概述 1.构造过程 今天给 ...

  8. Android 中的mvvm

    我们来了解一下MVVM模式与Databinding ,MVVM是一种模式,Databinding 是一种框架.DataBinding是一个实现数据和UI绑定的框架.而ViewModel和View可以通 ...

  9. JAVA 设计模式之策略模式

    定义:定义一组算法,将每个算法都封装起来,并且使他们之间可以互换. 类型:行为类模式 策略模式是对算法的封装,把一系列的算法分别封装到对应的类中,并且这些类实现相同的接口,相互之间可以替换.在前面说过 ...

  10. ASP.NET 5 和Entity Framework 7公告仓库

    ASP.NET 5 有一个公告仓库来介绍ASP.NET 5和 Entity Framework 7的主要变更说明,这个对于日夜更新的项目来说,很多人经常会遇到问题但是不知道去哪里寻找帮助,很多同学在做 ...