guxh的python笔记八:特殊方法
1,类的特殊方法
新建一个类,本章内容中的特殊方法如果不创建类或新增方法,默认使用的就是下面的类:
class Foo:
"""this is Foo"""
typecode = 'd' def __init__(self, x):
self.x = x def run(self):
return self.x f = Foo(1)
__doc__:类的描述信息
print(f.__doc__) # this is Foo
__module_:对象所属modul,如果是当前执行文件的即__main__,如果是import的,可以查看所属的module
print(f.__module__) # __main__
import pandas as pd
df = pd.DataFrame()
print(df.__module__) # pandas.core.frame
__class__:对象所属类,等效于type
print(f.__class__) # <class '__main__.Foo'>
print(type(f)) # <class '__main__.Foo'>
__dir__:
函数不带参数时,返回当前范围内的变量、方法和定义的类型列表;
for i in dir():
print(i) 输出为:
Foo
__annotations__
__builtins__
__cached__
__doc__
__file__
__loader__
__name__
__package__
__spec__
f
带参数时,返回参数的属性、方法列表。
for i in dir(Foo):
print(i) 输出为:
__class__
__delattr__
__dict__
__dir__
__doc__
__eq__
__format__
__ge__
__getattribute__
__gt__
__hash__
__init__
__init_subclass__
__le__
__lt__
__module__
__ne__
__new__
__reduce__
__reduce_ex__
__repr__
__setattr__
__sizeof__
__str__
__subclasshook__
__weakref__
run
typecode
类的实例比类多了实例属性:
print(set(dir(f)) - set(dir(Foo))) # {'x'}
print(set(dir(Foo)) - set(dir(f))) # set()
__mro__:打印类的层次结构
>>> FileNotFoundError.__mro__
(<class 'FileNotFoundError'>, <class 'OSError'>, <class 'Exception'>, <class 'BaseException'>, <class 'object'>)
__dict__:打印类/实例的属性
dict只能使用obj.__dict__,不能使用dict(obj),因为后者会被视为字典的初始化
打印所有实例的属性(不包括类属性):
f = Foo(1)
print(f.__dict__) # {'x': 1}
打印所有类属性(不包括实例的属性):
for k, v in Foo.__dict__.items():
print(k, v) 输出为:
__module__ : __main__
__doc__ : this is Foo
typecode : d
__init__ : <function Foo.__init__ at 0x000001AC45314620>
__dict__ : <attribute '__dict__' of 'Foo' objects>
__weakref__ : <attribute '__weakref__' of 'Foo' objects>
注意__dir__和__dict__的区别:前者显示类/实例所有的属性/方法(如果是实例显示的是类+实例的属性/方法),后者显示类/实例属性键值对(类和属性只会分别显示自己特有的)
__call__:让类的实例变为可调用
class Foo:
def __call__(self, *args, **kwargs):
return 1
print(Foo()()) # 1,第一次()是实例化,第二次()是调用
__get__、__set__、__delete__:描述符协议,属性的设置/取值/删除
__getattr__、__setattr__、__delattr__:动态属性的设值/取值/删除,详见类的属性
__getattribute__:获取已经存在的属性值,__getattr__是获取不存在的属性值的方法
__getitem__、__setitem__、__delitem__:[]运算符,分量的获取/设置/删除
class Foo:
def __init__(self, components):
self._components = sorted(components)
def __setitem__(self, key, value):
self._components[key] = value
def __getitem__(self, item):
return self._components[item]
def __repr__(self):
return '<Foo: {}>'.format(self._components)
访问与设置分量:
f = Foo([3, 5, 1, 9]) # <Foo: [1, 3, 5, 9]>
print(f)
print(f[1]) # 3
f[0] = 10
print(f) # <Foo: [10, 3, 5, 9]>
__enter__,__exit__:上下文管理器,先触发__enter__,再触发with代码块,最后触发__exit__
class Foo:
def __enter__(self):
return 'enter获取的内容' # 可以没有返回内容
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit时只需的内容')
with Foo() as f:
print(f) # f获取的是__enter__返回的结果
输出为:
enter获取的内容
exit时只需的内容
__slot__:存储实例属性方式改为元组方式
缺省存储实例属性是字典方式,在__dict__中,改为元组方式可以节省空间,但是属性范围受到slot元组限制
class Foo:
__slots__ = ('x', 'y')
__reversed__:反向迭代协议,让序列类型对象支持反向迭代,如果没有该协议,可以先把对象变成列表再用列表的反向迭代协议
class Foo:
def __init__(self, components):
self.components = [x*x for x in components] def __reversed__(self):
return reversed(self.components) # 委托给self.components背后的生成器 f = Foo([1, 3, 5, 7, 9])
for i in reversed(f):
print(i)
__format__:
_formats = {'ymd': '{d.year}-{d.month}-{d.day}',
'mdy': '{d.month}/{d.day}/{d.year}'}
class Foo:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def __format__(self, code):
if code == '':
code = 'ymd'
fmt = _formats[code]
return fmt.format(d=self)
f = Foo(2019, 1, 25)
print(format(f)) # 2019-1-25
print(format(f, 'mdy')) # 1/25/2019
__new__:可以实例化时跳过构造函数
class Date:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
>>>d = Date.__new__(Date)
>>>d
<__main__.Date object at 0x10b353400>
>>>d.year
AttributeError: 'Date' object has no attribute 'year'
__metaclass__:待补充
__init__:略
__del__:略
__str__:略
__repr__:返回的内容最好符合obj = eval(repr(obj)),即返回内容可以直接用来实例化
没有定义__repr__或者__str__时,返回的是对象的内存地址:
class User:
def __init__(self, user_id):
self.user_id = user_id
u = User(3)
print(u) # <__main__.User object at 0x000002E85D7383C8>
使用猴子补丁定义__repr__,再打印u:
def repr(instance):
return 'User({})'.format(instance.user_id)
User.__repr__ = repr
u = User(3)
print(u) # User(3)
u的repr返回内容可以直接拿来实例化:
u1 = eval(repr(u))
print(u1) # User(3)
print(u is u1) # False,u和u1不是同一个实例
__contain__:in测试首先调用的特殊方法,下面自建了一个类似字典的Dict类,但是in测试测的是key,而不是values:
class Dict:
def __init__(self, **kwargs):
self.map = kwargs
def __contains__(self, item):
if item in self.map.values():
return True
d = Dict(a=1, b=2)
print('a' in d) # False
print(1 in d) # True
2,操作需要支持的特殊方法
序列:__len__,__getitem__
切片:__getitem__
迭代/元组拆包:1)__iter__;2)__getitem__(index从0开始)
可散列:__hash__,__eq__
in测试:1)__contains__;2)__iter__;3)__getitem__
描述符:__set__,__get__,__delete__ (可部分实现)
动态属性存取:__getattr__、__setattr__、__delattr__
[]分量存取:__getitem__、__setitem__、__delitem__
运算符+= :1)__iadd__,2)__add__
上下文管理器:__enter__,__exit__
反向迭代:__reversed__
guxh的python笔记八:特殊方法的更多相关文章
- guxh的python笔记一:数据类型
1,基本概念 1.1,数据类型 基本数据类型:字符串,数字,布尔等 引用数据类型:相对不可变(元组),可变(列表,字典,集合等) 基本数据类型存放实际值,引用数据类型存放对象的地址(即引用) ==:判 ...
- guxh的python笔记七:抽象基类
1,鸭子类型和白鹅类型 1.1,白鹅类型 白鹅类型对接口有明确定义,比如不可变序列(Sequence),需要实现__contains__,__iter__,__len__,__getitem__,__ ...
- guxh的python笔记五:面向对象
1,面向对象编程思想 类:一类具有相同属性的抽象 属性(静态属性):实例变量.类变量.私有属性 方法(动态属性):构造函数.析构函数(默认就有).函数.私有函数 对象/实例:类经过实例化后,就是对象/ ...
- guxh的python笔记二:函数基础
1,函数的参数 1.1,查看函数的参数类型 def run(a, *args, b, **kwargs): return a + b 可以通过如下方式查看参数类型: import inspect k ...
- guxh的python笔记三:装饰器
1,函数作用域 这种情况可以顺利执行: total = 0 def run(): print(total) 这种情况会报错: total = 0 def run(): print(total) tot ...
- guxh的python笔记十:包和模块
1,包和模块 包package:本质就是一个文件夹/目录,必须带一个__init.__.py的文件 模块module:.py结尾的python文件 2,导入方法 import pandas, coll ...
- guxh的python笔记十一:异常处理
1,抓错方法 name = [0, 1, 2] try: name[3] except IndexError as exc: # 抓单个错误,打印错误信息e print(exc) except (In ...
- guxh的python笔记六:类的属性
1,私有属性 class Foo: def __init__(self, x): self.x = x 类的属性在实例化之后是可以更改的: f = Foo(1) print(f.x) # 1 f.x ...
- guxh的python笔记四:迭代
1,可迭代对象iterable,迭代器iterator,生成器generator 可迭代对象iterable: 实现__iter__方法的类.__iter__方法返回iterator或者generat ...
随机推荐
- ZOJ 4062 - Plants vs. Zombies - [二分+贪心][2018 ACM-ICPC Asia Qingdao Regional Problem E]
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4062 题意: 现在在一条 $x$ 轴上玩植物大战僵尸,有 $n$ ...
- threw exception [Handler processing failed; nested exception is java.lang.NoClassDefFoundError: com/dyuproject/protostuff/MapSchema$MessageFactory] with root cause
错误记录 前几天朋友问我一个错误,顺便记录一下,关于redis 工具类,protostuff序列化报错. threw exception [Handler processing failed; nes ...
- react native出现 undefined is not a function_this4.错误函数无法识别
该函数可能里可能有this,的上个函数this要绑定bind(this)
- linux以16进制查看文件
vim 先用vim -b data 以2进制打开文件,然后用xxd工具转化,在vim的命令行模式下: :%!xxd --将当前文本转化为16进制格式 :%!xxd -r --将16 ...
- CentOS 7 服务端口表
# Note that it is presently the policy of IANA to assign a single well-known# port number for both T ...
- SqlServer父节点与子节点查询及递归
在最近老是用到这个SQL,所以记下来了: 1:创建表 CREATE TABLE [dbo].[BD_Booklet]( [ObjID] [int] IDENTITY(1,1) NOT NULL, [P ...
- 第二篇——Struts2的Action搜索顺序
Struts2的Action的搜索顺序: 地址:http://localhost:8080/path1/path2/student.action 1.判断package是否存在,例如:/pat ...
- 详解Python变量在内存中的存储
这篇文章主要是对python中的数据进行认识,对于很多初学者来讲,其实数据的认识是最重要的,也是最容易出错的.本文结合数据与内存形态讲解python中的数据,内容包括: 引用与对象 可变数据类型与不可 ...
- swagger 自动生成接口测试用例
---整体更新一波--- 1.实际工作中,因为要动手输入的地方比较多,自动生成的异常接口用例感觉用处不大,就先去掉了,只保留了正常的: 2.接口有改动的,如果开发人员没有及时告知或没有详细告知,会增加 ...
- 20190409Liunx中计划任务及压缩归档week2_day1
计划任务介绍 我们可以通过一些设置.来让电脑定时提醒我们该做什么事了.或者我们提前设置好,告诉电脑你几点做什么几点做什么,这种我们就叫它定时任务.而遇到一些需要执行的事情或任务.我们也可以通过命令来告 ...