文章目录
特殊属性查看属性魔术方法实例化可视化hash运算符容器相关方法可调用对象
特殊属性
属性说明
__name __类、函数、方法等的名字,实例没有__name__的属性__module __类定义所在的模块名__class __对象或类所属的类__bases __类的基类的元组,顺序为它们在基类列表中出现的顺序__doc __类、函数的文档字符串,如果没有定义则为 None__mro __类的mro,class.mro()返回的结果的保存在 __mro ____dict __类或实例的属性,可写的字典
`
查看属性
__dir __ 方法
方法说明
__dir __返回类或者对象的所有成员 名称列表。通过内建函数 dir() 操作实例就是调用 __dir __()。
如果dir([obj])参数obj包含方法__dir__(),该方法将被调用。如果参数obj不包含__dir__(),该方法将最大限度地收集属性信息。
dir(obj)对于不同类型的对象obj具有不同的行为:
如果对象是模块,返回的列表包含模块的属性名和变量名如果对象是类,返回的列表包含类的属性名,及它的祖先类的属性名如果是类的实例
有__dir__方法,返回可迭代对象的返回值没有__dir__方法,则尽可能收集实例的属性名、类的属性和祖先类的属性名
如果dir([obj])中的obj不写,则分3种情况
在模块中,返回模块的属性和变量名在函数中,返回本地作用域的变量名在方法中,返回本地作用域的变量名
dir 方法一定要返回一个可迭代对象
不管__dir__ 方法返回的是什么要的可迭代对象,最终都会被解释器转换为一个列表
class Animal:
def __init__(self
,name
):
self
.name
= name
cat
= Animal
('cat')
print(dir(cat
))
-------------------------------------
['__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__', 'name']
class Animal:
def __init__(self
,name
):
self
.name
= name
def __dir__(self
):
return ['a','b']
cat
= Animal
('cat')
print(dir(cat
))
------------------------------------
['a', 'b']
__dir __() 方法测试
class Person:
def show(self
):
a
= 100
t
= int(a
)
print(dir())
print(locals())
def test(a
=50, b
=100):
c
= 150
print(dir())
print(locals())
print(globals())
Person
().show
()
test
()
print(dir())
-------------------------------------------------------------------------------
['a', 'self', 't']
{'self': <__main__
.Person
object at
0x000001A581F4DAC8>, 'a': 100, 't': 100}
['a', 'b', 'c']
{'a': 50, 'b': 100, 'c': 150}
['Person', '__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'test']
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external
.SourceFileLoader
object at
0x00000220A1AE6668>, '__spec__': None, '__annotations__': {}, '__builtins__': <module
'builtins' (built
-in)>, '__file__': 'F:/pycharm/test/Animal.py', '__cached__': None, 'Person': <class '__main__.Person'>, 'test': <function test at
0x00000220A38F2378>}
内建函数
locals() 返回当前作用域中的变量字典globals() 当前模块全局变量的字典
魔术方法
魔术方法的分类
创建、初始化与销毁 __new __ 、__init __ 、__del __hashbool可视化运算符重载容器和大小可调用对象上下文管理反射描述器其他杂项
实例化
方法意义
__new __实例化一个对象,该方法需要返回一个值,如果该值不是cls的实例,则不会调用__init__该方法永远都是静态方法
class Person:
def __new__(cls
, *args
, **kwargs
):
print(cls
)
print(args
)
print(kwargs
)
return None
def __init__(self
, name
):
self
.name
= name
tom
= Person
("tom")
print(tom
)
----------------------------------------------------
<class '__main__.Person'>
('tom',)
{}
None
__new__方法很少使用,即使创建了该方法,也会使用return super().new(cls)基类object的__new__方法来创建实例并返回
可视化
方法意义
__str __str()函数、format()函数、print()函数调用,需要返回对象的字符串表达。如果没有定义,就去调用__repr__方法返回字符串表达,如果__repr__没有定义,就直接返回对象的内存地址信息__repr __内建函数repr()对一个对象获取字符串表达。调用__repr__方法返回字符串表达,如果__repr__也没有定义,就直接返回object的定义就是显示内存地址信息__bytes __bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象
使用方法如下
class Person:
def __init__(self
, name
, age
=18):
self
.name
= name
self
.age
= age
def __repr__(self
):
return 'repr: {},{}'.format(self
.name
, self
.age
)
def __str__(self
):
return 'str: {},{}'.format(self
.name
, self
.age
)
def __bytes__(self
):
return "{} is {}".format(self
.name
, self
.age
).encode
()
tom
= Person
('tom')
print(tom
)
print('{}'.format(Person
('tom')))
print([Person
('tom')])
print(tom
.__dict__
)
----------------------------------------------------
str: tom
,18
str: tom
,18
[repr: tom
,18]
{'name': 'tom', 'age': 18}
hash
方法意义
__hash __内建函数hash()调用的返回值,返回一个整数。如果定义这个方法该类的实例就可hash。__eq __对应==操作符,判断2个对象是否相等,返回bool值定义了这个方法,如果不提供__hash__方法,那么实例将不可hash了
class Person:
def __init__(self
, name
, age
=18):
self
.name
= name
self
.age
= age
def __hash__(self
):
return 100
A
= Person
('tom')
tom
= Person
('tom')
print(hash(tom
),hash(A
))
print({A
,tom
})
----------------------------------------------------
100 100
{<__main__
.Person
object at
0x0000014463288358>, <__main__
.Person
object at
0x0000014462F86710>}
要去重,必须还要相等,如下
class Person:
def __init__(self
, name
, age
=18):
self
.name
= name
self
.age
= age
def __hash__(self
):
return 100
def __eq__(self
, other
):
return self
.name
== other
.name
print(hash(tom
),hash(A
))
print({A
,tom
})
----------------------------------------------------
100 100
{<__main__
.Person
object at
0x000002BA70E46710>}
去重必须要满足 hash值一样,并且内容相等
方法意义
__ bool__内建函数bool(),或者对象放在逻辑表达式的位置,调用这个函数返回布尔值。没有定义__bool__(),就找__len__()返回长度,非0为真。如果__len__()也没有定义,那么所有实例都返回真
运算符
特殊方法含义
<, <=, ==, >, >=, !=__lt __, __le __, __eq __, __gt __, __ge __, __ne __比较运算符+, -, *, /, %, //, **, divmod__add __, __sub __, __mul __, __truediv __, __mod __, __floordiv __, __pow __, __divmod __算数运算符,移位、位运算也有对应的方法+=, -=, *=, /=, %=, //=, **=__iadd __, __isub __, __imul __, __itruediv __, __imod __, __ifloordiv __, __ipow __
实现Point类的2个实例相加,减
class Point:
def __init__(self
,x
,y
):
self
.x
= x
self
.y
= y
def __add__(self
,other
):
return (self
.x
+ other
.x
, self
.y
+ other
.y
)
def __sub__(self
,other
):
return (self
.x
- other
.x
, self
.y
- other
.y
)
def __str__(self
):
return str((self
.x
, self
.y
))
p1
= Point
(2,3)
p2
= Point
(5,6)
print(p1
+p2
)
print(p1
-p2
)
------------------------------------------------------------------------
(7, 9)
(-3, -3)
__ isub __方法定义,一般会in-place就地来修改自身如果没有定义__isub__方法,则会调用__sub __
class Person:
def __init__(self
, name
, age
):
self
.name
= name
self
.age
= age
def __eq__(self
, other
):
return self
.age
== other
.age
def __gt__(self
, other
):
return self
.age
> other
.age
def __ge__(self
, other
):
return self
.age
>= other
.age
tom
= Person
('tom', 20)
jerry
= Person
('jerry', 16)
print(tom
> jerry
) >>>True
print(tom
< jerry
) >>>False
print(tom
>= jerry
) >>>True
print(tom
<= jerry
) >>>False
print(tom
== jerry
) >>>False
print(tom
!= jerry
) >>>True
容器相关方法
方法意义
__len __内建函数len(),返回对象的长度(>=0的整数),如果把对象当做容器类型看,就如同list或者dict。bool()函数调用的时候,如果没有__bool__()方法,则会看__len__()方法是否存在,存在返回非0为真__iter __迭代容器时,调用,返回一个新的迭代器对象__contains __in 成员运算符,没有实现,就调用__iter__方法遍历__getitem __实现self[key]访问。序列对象,key接受整数为索引,或者切片。对于set和dict,key为hashable。key不存在引发KeyError异常__setitem __和__getitem__的访问类似,是设置值的方法__missing __字典或其子类使用__getitem__()调用时,key不存在执行该方法
class Cart:
def __init__(self
):
self
.items
= []
def additem(self
,item
):
self
.items
.append
(item
)
return self
def __len__(self
):
return len(self
.items
)
def __getitem__(self
,index
):
return self
.items
[index
]
def __setitem__(self
,key
,value
):
return self
.items
[key
] == value
def __iter__(self
):
return iter(self
.items
)
def __add__(self
,other
):
self
.items
.append
(other
)
return self
def __str__(self
):
return str(self
.items
)
p1
= Cart
()
p1
.additem
('cup')
p1
.additem
('phone').additem
('keyboard')
print(p1
)
-----------------------------------------------------------
['cup', 'phone', 'keyboard']
可调用对象
方法意义
__call __类中定义一个该方法,实例就可以像函数一样调用
举例:累加
class Add:
def __call__(self
, *args
):
ret
= 0
for i
in args
:
ret
+= i
self
.ret
= ret
return self
.ret
adder
= Add
()
print(adder
(1,2,3))
----------------------------------
6