Python中几个以“__”开头的方法介绍总结

__dir__ -> 看个小例子就知道了

In [1]: class T(object):
   ...:     pass
   ...:
In [2]: t = T()
In [3]: t.<Tab>
啥也没有...

In [4]: class T2(object):
   ...:     def __dir__(self):
   ...:         return ['a', 'b']
   ...:
In [5]: t = T2()
In [6]: t.
t.a  t.b
In [7]: dir(t)
Out[7]: ['a', 'b']

看出来了把, 不解释, 但是这个__dir__是相对于类的实例有效果的.

__slots__

这个在我初学python的时候就被模糊了, 原来的理解是它的出现替代了__dict__,也就是说你只能给__slots__ 这个变量列表项的属性赋值. 对外的接口减少了,也安全了. 后来看了这篇Saving 9 GB of RAM with Python’s slots. 好久不做运维了,在生产环境究竟怎么样我无法定论, 也提到了,在对象实例很多的时候他能帮助减少内存, 详见https://www.safaribooksonline.com/library/view/python-cookbook-3rd/9781449357337/ch08s04.html. 这里来个小实验(在Hacker News也被讨论过https://news.ycombinator.com/item?id=6750187)

代码例子(我对细节做注释):

# coding=utf-8
import sys
from itertools import starmap, product

class SlotTest(object):
    # __slots__ = ['x', 'y', 'z'] 主要对比去掉这句和包含这句程序内存占用

    def __init__(self, x, y, z):
            self.x = x
                    self.y = y
                            self.z = z

    def __str__(self):
            return "{} {} {}".format(self.x, self.y, self.z)

p = product(range(10000), range(20), [4]) # 创建0-1000 & 0-20 & 4 的笛卡尔积
a = list(starmap(SlotTest, p)) # 相当于对每个SlotTest实例化,实例化的格式是p的长度

print a[0]
sys.stdin.read(1)

结果对比:

$pmap -x `ps -ef|grep test_slot.py|grep -v grep|awk '{print $2}'`|grep total # 未使用__slots__
  total kB          103496   76480   73728
$pmap -x `ps -ef|grep test_slot.py|grep -v grep|awk '{print $2}'`|grep total # 使用了__slots__
  total kB           49960   22888   20136

结果很明显,内存占用减少了很多…

__weakref__ 弱引用

首先先说下weakref: 弱引用,与强引用相对,是指不能确保其引用的对象不会被垃圾回收器回收的引用。一个对象若只被弱引用所引用,则被认为是不可访问(或弱可访问)的,并因此可能在任何时刻被回收. 在Python中,当一个对象的引用数目为0的时候,才会被从内存中回收. 但是被循环引用呢?

In [1]: import weakref

In [2]: import gc

In [3]: class Obj(object):
   ...:     def a(self):
   ...:         return 1
   ...:
In [4]: obj = Obj()

In [5]: s = obj

In [6]: gc.collect() # 不可达引用对象的数量
Out[6]: 3

In [7]: print s is obj
True

In [8]: obj = 1 # 最初的被引用的对象改变了.

In [9]: gc.collect()
Out[9]: 0

In [10]: s is None # s还是指向了Obj 引用计数为1
Out[10]: False

In [11]: s
Out[11]: <__main__.Obj at 0x2b36510>

----华丽的分割一下

In [12]: obj = Obj()

In [13]: r = weakref.ref(obj) # 让obj变成那个弱引用

In [14]: gc.collect()
Out[14]: 211

In [15]: r() is obj
True

In [16]: obj = 1

In [17]: gc.collect()
Out[17]: 0

In [18]: r() is None # 弱引用计数器没有增加,所以当obj不在引用Obj的时候,Obj对象就被释放了
Out[18]: True

好吧, 我的总结是弱引用是个好东西, 但是加了__slots__就不支持弱引用了. 所以需要__weakref__

In [9]: class T3(object):
   ...:     __slots__ = []
      ...:

In [10]: class T4(object):
   ....:     __slots__ = '__weakref__'  # 这样就支持了weakref
      ....:

In [11]:  import weakref

In [12]: t3 = T3()

In [13]: t4 = T4()

In [14]: weakref.ref(t3)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-14-bdb7ab7ac3bc> in <module>()
----> 1 weakref.ref(t3)

TypeError: cannot create weak reference to 'T3' object

In [15]: weakref.ref(t4)
Out[15]: <weakref at 0x2766f70; to 'T4' at 0x2586fd8>

__contains__ 判断某值 in/not in 实例

In [1]: class NewList(object):
   ...:     def __init(self, values):
   ...:         self.values = values
   ...:     def __contains__(self, value):
   ...:         return value in self.values
   ...:
In [2]: l = NewList([1, 2, 3, 4])

In [3]: 4 in l
Out[3]: True

In [4]: 10 in l
Out[4]: False

__missing__

最初看这个特殊方法是看python标准库的源码的时候(collections#L421):

class Counter(dict):
    ...

    def __missing__(self, key):
        'The count of elements not in the Counter is zero.'
        # Needed so that self[missing_item] does not raise KeyError
        return 0

什么意思呢?

In [6]: c = collections.Counter({'a':1})

In [7]: c['b'] # 没有键的count设置默认值0
Out[7]: 0

很多人可能看过这个(关于defaultdict的ppt)[http://discorporate.us/jek/talks/defaultdict/]. 内容就不说了, 讲的非常好.

时间: 2024-11-06 07:32:31

Python中几个以“__”开头的方法介绍总结的相关文章

Python中条件选择和循环语句使用方法介绍_python

同C语言.Java一样,Python中也存在条件选择和循环语句,其风格和C语言.java的很类似,但是在写法和用法上还是有一些区别.今天就让我们一起来了解一下. 一.条件选择语句 Python中条件选择语句的关键字为:if .elif .else这三个.其基本形式如下: 复制代码 代码如下: if condition: block elif condition: block ... else block 其中elif和else语句块是可选的.对于if和elif只有condition为True时,

Python中函数的参数传递与可变长参数介绍

  这篇文章主要介绍了Python中函数的参数传递与可变长参数介绍,本文分别给出多个代码实例来讲解多种多样的函数参数,需要的朋友可以参考下 1.Python中也有像C++一样的默认缺省函数 代码如下: def foo(text,num=0): print text,num foo("asd") #asd 0 foo("def",100) #def 100 定义有默认参数的函数时,这些默认值参数 位置必须都在非默认值参数后面. 调用时提供默认值参数值时,使用提供的值,

python中日期和时间格式化输出的方法小结

 这篇文章主要介绍了python中日期和时间格式化输出的方法,实例总结了Python常见的日期与事件操作技巧,非常具有实用价值,需要的朋友可以参考下     本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一

Python中处理字符串的相关的len()方法的使用简介

  这篇文章主要介绍了Python中处理字符串的相关的len()方法的使用简介,是Python入门的基础知识,需要的朋友可以参考下 len()方法返回字符串的长度. 语法 以下是len()方法的语法: ? 1 len( str ) 参数 NA 返回值 此方法返回的字符串的长度. 例子 下面的例子显示了len()方法的使用. ? 1 2 3 4 5 #!/usr/bin/python   str = "this is string example....wow!!!";   print

Python中转换角度为弧度的radians()方法

  这篇文章主要介绍了Python中转换角度为弧度的radians()方法,是Python入门中的基础知识,需要的朋友可以参考下 radians()方法把角度转化为弧度角x. 语法 以下是radians()方法的语法: ? 1 radians(x) 注意:此函数是无法直接访问的,所以我们需要导入math模块,然后需要用math的静态对象来调用这个函数. 参数 x -- 这必须是一个数值. 返回值 此方法返回一个角度的弧度值. 例子 下面的示例演示radians()方法的使用. ? 1 2 3 4

python中for语句简单遍历数据的方法

  这篇文章主要介绍了python中for语句简单遍历数据的方法,以一个简单实例形式分析了Python中for语句遍历数据的技巧,具有一定参考借鉴价值,需要的朋友可以参考下 本文实例讲述了python中for语句简单遍历数据的方法.分享给大家供大家参考.具体如下: 代码如下: for name in ["kak", "John", "Mani", "Matt"]: print(name) 运行结果如下: 代码如下: kak J

介绍Python中的try和finally和with方法

  这篇文章主要介绍了Python中的try和finally和with方法,是Python学习当中的基础知识,需要的朋友可以参考下 用 Python 做一件很平常的事情: 打开文件, 逐行读入, 最后关掉文件; 进一步的需求是, 这也许是程序中一个可选的功能, 如果有任何问题, 比如文件无法打开, 或是读取出错, 那么在函数内需要捕获所有异常, 输出一行警告并退出. 代码可能一开始看起来是这样的 ? 1 2 3 4 5 6 7 8 def read_file(): try: f = open('

Python中实现参数类型检查的简单方法

  这篇文章主要介绍了Python中实现参数类型检查的简单方法,本文讲解使用装饰器实现参数类型检查并给出代码实例,需要的朋友可以参考下 Python是一门弱类型语言,很多从C/C++转过来的朋友起初不是很适应.比如,在声明一个函数时,不能指定参数的类型.用C做类比,那就是所有参数都是void*类型!void类型强制转换在C++中被广泛地认为是个坏习惯,不到万不得已是不会使用的. Python自然没有类型强制转换一说了,因为它是动态语言.首先,所有对象都从Object继承而来,其次,它有强大的内省

python中日期和时间格式化输出的方法小结_python

本文实例总结了python中日期和时间格式化输出的方法.分享给大家供大家参考.具体分析如下: python格式化日期时间的函数为datetime.datetime.strftime():由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一个参数的使用方法及范例. 下面是格式化日期和时间时可用的替换符号 %a 输出当前是星期几的英文简写 >>> import datetime >&