内置方法
str() & repr()
重写 __str__()
函数类似重写 Java 类中的 toString()
方法。当没有重写 __str__()
但重写了 __repr__()
方法时,__repr__()
方法会充当一个 __str__()
方法的替代方法执行。
class Person1:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "name:{} age:{}".format(self.name, self.age)
p1 = Person1('张三', 18)
print(p1) # name:张三 age:18
class Person2:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return "name:{} age:{}".format(self.name, self.age)
p2 = Person2('张三', 18)
print(p1) # name:张三 age:18
del()
销毁一个对象的时候执行,类似 Java 中的析构函数。
class A:
def __del__(self):
print("from del")
a = A()
del a # from del
getitem() & setitem() & delitem()
以 对象[]
的形式操作对象属性时会执行。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __getitem__(self, item):
print("from __getitem__:{}".format(item))
return self.__dict__[item]
def __setitem__(self, key, value):
print("from __setitem__:{} = {}".format(key, value))
self.__dict__[key] = value
def __delitem__(self, key):
print("from __delitem__:{}".format(key))
p = Person('张三', 18)
name = p['name'] # from __getitem__:name
print(name) # 张三
print(p.age) # 18
p['age'] = 20 # from __setitem__:age = 20
print(p.age) # 20
# 和@property.deleter相似 del时只是触发对应方法 并不是真的删除
del p['age'] # from __delitem__:age
print(p.age) # 20
new()
创建对象,类似 Java 中的构造函数,在 __init__()
函数之前执行。
class Person:
def __init__(self, name, age):
print('from __init__()')
self.name = name
self.age = age
def __new__(cls, *args, **kwargs):
print('from __new__()')
return object.__new__(cls)
p = Person('张三', 18)
# result:
# from __new__()
# from __init__()
call()
让一个类的实例成为一个 callable 对象。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __call__(self, *args, **kwargs):
print('name:{} age:{}'.format(self.name, self.age))
p = Person('张三', 18)
print(callable(p)) # True
p() # name:张三 age:18
len()
将一个对象传入 len()
函数实际上就是调用这个对象的 __len__()
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __len__(self):
return len(self.name)
print(len(Person('张三', 18))) # 2
hash()
对 hash()
函数传入一个对象实际上就是调用这个对象的 __hash__()
方法。
class Person:
def __init__(self, no, name, age):
self.no = no
self.name = name
self.age = age
def __hash__(self):
return self.no
p = Person(1, '张三', 18)
print(hash(p)) # 1
eq()
使用 ==
判断两个对象是否相等时,依据 __eq__()
函数返回的值。类似 Java 中的 equals()
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name
p1 = Person('张三', 19)
p2 = Person('张三', 18)
print(p1 == p2) # True
add()
在两个对象之间使用 +
连接时会调用这个对象的 __add__()
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name
def __add__(self, other):
return self.age + other.age
p1 = Person('tom', 12)
p2 = Person('jerry', 18)
print(p1 + p2) # 30
enter() & exit()
当使用 with
关键字修饰对象执行一个代码块时,在执行代码块之前会调用这个对象的 __enter__()
方法,在代码块中的代码执行完后退出代码块之前会执行这个对象的 __exit__()
方法。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name
def __enter__(self):
print('from __enter__')
def __exit__(self, exc_type, exc_val, exc_tb):
print('fron __exit__')
p = Person('tom', 12)
with p:
print('from 代码块')
# from __enter__
# from 代码块
# fron __exit__
doc()
使用 obj.__doc__
能够获取到 obj
所属类的注释文档信息。
class Person:
"""
这是一段注释
"""
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('tom', 12)
print(p.__doc__)
# 这是一段注释
dict()
使用 obj.__dict__
能够以字典类型获取到 obj
对象中所有的字段及其值。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('tom', 12)
print(p.__dict__,type(p.__dict__))
# {'name': 'tom', 'age': 12} <class 'dict'>
iter()
在类的内部定义 __iter__()
方法可以将该类的实例转为可迭代的对象。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __iter__(self):
# 必须返回一个迭代器,生成器也是迭代器的一种,所以可以使用 yield
return iter([1, 2, 3, 4])
p = Person('tom', 12)
for i in p:
print(i)
# 1
# 2
# 3
# 4
补充
单例模式
class Single:
instance = None
def __new__(cls, *args, **kwargs):
if cls.instance:
return cls.instance
cls.instance = object.__new__(cls)
return cls.instance
o1 = Single()
o2 = Single()
print(o1) # <__main__.Single object at 0x00000000021EDAC8>
print(o2) # <__main__.Single object at 0x00000000021EDAC8>
扑克牌
from collections import namedtuple
from random import choice, shuffle
CardTuple = namedtuple('Card', ['suit', 'rank'])
class Card:
def __init__(self):
suit_list = ['红桃', '黑桃', '梅花', '方块']
rank_list = [str(i) for i in range(2, 11)] + ['J', 'Q', 'K', 'A']
self.card_list = [CardTuple(suit, rank) for rank in rank_list for suit in suit_list]
def __str__(self):
return str(self.card_list)
def __len__(self):
return len(self.card_list)
def __getitem__(self, item):
return self.card_list[item]
def __setitem__(self, key, value):
self.card_list[key] = value
# 一幅扑克牌
card = Card()
print(
card) # [Card(suit='红桃', rank='2'), Card(suit='黑桃', rank='2'), Card(suit='梅花', rank='2'), Card(suit='方块', rank='2'), Card(suit='红桃', rank='3'), Card(suit='黑桃', rank='3'), Card(suit='梅花', rank='3'), Card(suit='方块', rank='3'), Card(suit='红桃', rank='4'), Card(suit='黑桃', rank='4'), Card(suit='梅花', rank='4'), Card(suit='方块', rank='4'), Card(suit='红桃', rank='5'), Card(suit='黑桃', rank='5'), Card(suit='梅花', rank='5'), Card(suit='方块', rank='5'), Card(suit='红桃', rank='6'), Card(suit='黑桃', rank='6'), Card(suit='梅花', rank='6'), Card(suit='方块', rank='6'), Card(suit='红桃', rank='7'), Card(suit='黑桃', rank='7'), Card(suit='梅花', rank='7'), Card(suit='方块', rank='7'), Card(suit='红桃', rank='8'), Card(suit='黑桃', rank='8'), Card(suit='梅花', rank='8'), Card(suit='方块', rank='8'), Card(suit='红桃', rank='9'), Card(suit='黑桃', rank='9'), Card(suit='梅花', rank='9'), Card(suit='方块', rank='9'), Card(suit='红桃', rank='10'), Card(suit='黑桃', rank='10'), Card(suit='梅花', rank='10'), Card(suit='方块', rank='10'), Card(suit='红桃', rank='J'), Card(suit='黑桃', rank='J'), Card(suit='梅花', rank='J'), Card(suit='方块', rank='J'), Card(suit='红桃', rank='Q'), Card(suit='黑桃', rank='Q'), Card(suit='梅花', rank='Q'), Card(suit='方块', rank='Q'), Card(suit='红桃', rank='K'), Card(suit='黑桃', rank='K'), Card(suit='梅花', rank='K'), Card(suit='方块', rank='K'), Card(suit='红桃', rank='A'), Card(suit='黑桃', rank='A'), Card(suit='梅花', rank='A'), Card(suit='方块', rank='A')]
# 扑克牌张数
print(len(card)) # 52
# 取第十张
print(card[10 - 1]) # Card(suit='黑桃', rank='4')
# 随机抽取一张
print(choice(card)) # Card(suit='方块', rank='7')
# 洗牌
shuffle(card)
print(
card) # [Card(suit='黑桃', rank='8'), Card(suit='梅花', rank='6'), Card(suit='黑桃', rank='2'), Card(suit='红桃', rank='4'), Card(suit='梅花', rank='4'), Card(suit='红桃', rank='K'), Card(suit='方块', rank='9'), Card(suit='梅花', rank='7'), Card(suit='梅花', rank='9'), Card(suit='方块', rank='4'), Card(suit='红桃', rank='7'), Card(suit='黑桃', rank='J'), Card(suit='红桃', rank='8'), Card(suit='梅花', rank='K'), Card(suit='红桃', rank='J'), Card(suit='黑桃', rank='6'), Card(suit='红桃', rank='A'), Card(suit='红桃', rank='10'), Card(suit='梅花', rank='5'), Card(suit='方块', rank='6'), Card(suit='方块', rank='10'), Card(suit='方块', rank='8'), Card(suit='方块', rank='7'), Card(suit='黑桃', rank='Q'), Card(suit='方块', rank='A'), Card(suit='红桃', rank='6'), Card(suit='梅花', rank='8'), Card(suit='梅花', rank='J'), Card(suit='梅花', rank='3'), Card(suit='方块', rank='J'), Card(suit='方块', rank='5'), Card(suit='梅花', rank='2'), Card(suit='黑桃', rank='4'), Card(suit='梅花', rank='A'), Card(suit='黑桃', rank='3'), Card(suit='黑桃', rank='5'), Card(suit='方块', rank='K'), Card(suit='红桃', rank='Q'), Card(suit='方块', rank='3'), Card(suit='方块', rank='2'), Card(suit='黑桃', rank='A'), Card(suit='黑桃', rank='7'), Card(suit='方块', rank='Q'), Card(suit='黑桃', rank='9'), Card(suit='红桃', rank='2'), Card(suit='红桃', rank='9'), Card(suit='黑桃', rank='10'), Card(suit='梅花', rank='10'), Card(suit='红桃', rank='3'), Card(suit='红桃', rank='5'), Card(suit='黑桃', rank='K'), Card(suit='梅花', rank='Q')]
对象去重
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p1 = Person('张三', 18)
p2 = Person('张三', 18)
print(set([p1, p2])) # {<__main__.Person object at 0x000000000273DBA8>, <__main__.Person object at 0x000000000273DAC8>}
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __eq__(self, other):
return self.name == other.name and self.age == other.age
def __hash__(self):
return hash(self.name + str(self.age))
p1 = Person('张三', 18)
p2 = Person('张三', 18)
print(set([p1, p2])) # {<__main__.Person object at 0x0000000002702860>}
使用 set()
给对象的去重是同时依赖对象的 __hash__()
和 __eq__()
函数的。
评论区