类的成员包括变量(类变量和实例变量),方法(绑定方法,类方法,静态方法)和属性(@property)
以双下划线开始的变量,方法和属性被称作私有成员,不能直接被外部调用。并且,私有成员无法被继承
python 是多继承,继承顺序是从下至上,从左往右,如果有第一顺位父类的类变量和方法优先被继承,后续顺位的父类的同名类变量和方法则会再被继承
多继承中,需要在子类的构造函数中显示的调用多个父类的构造函数,才能继承多个父类的实例变量,但实例变量的继承关系是后续顺位覆盖前面顺位的实例变量,这点和类变量和方法的继承关系不一样
显示调用父类构造函数有两种方法,只有第一种方法可以调用多继承中的多个父类构造函数
多继承中,如果不实现子类的构造函数,默认使用第一顺位父类的构造函数。这时,如果后续顺位的父类构造函数中有入参,在调用继承的后续顺位父类方法时,可能出现找不到某个变量的情况,原因是后续顺位父类没有调用构造函数传参
三种方法均可以被类和对象调用,主要是使用场景的不同,根据是否需要self 和 cls参数判断实现哪种类型的方法
普通的类内方法
class A:
def f0(self):
pass
类内方法,不带self 参数,取而代之的是cls参数,并且被 @classmethod 装饰的方法
class A:
@classmethod
def f1(cls):
pass
类内方法,不带self和cls参数,并且被 @staticmethod 装饰的方法
class A:
@staticmethod
def f2():
pass
内置装饰器 @property 可以将方法变成实例变量的get 操作。但此时有可能会和真实的实例变量重名。
def __new__(cls, *args, **kwargs):
'''创建空实例,如果没有实现,则调用object 的此方法'''
'''最先被调用的方法'''
return object.__new__(cls)
def __init__(self):
'''初始化实例'''
pass
def __call__(self, *args, **kwargs):
'''使类实例变成可调用对象'''
pass
def __str__(self):
'''使类实例中的数据可变成字符串,可被str和print函数调用'''
#直接调用即可将实例变量以字典的形式返回
t=Test()
t.__dict__
class Test:
def __getitem__(self, item):
'''以字典访问的方式查找实例变量'''
pass
def __setitem__(self, key, value):
'''以字典插入数据的方式对实例变量赋值'''
print(key, value)
pass
def __delitem__(self, key):
'''以del 的方式删除实例变量'''
pass
t = Test()
t['k1'] = 1 #以字典方式赋值数据时,实际是调用了 __setitem__ 方法
print(t['k1']) #实际是调用了 __getitem__ 方法
del t['k1'] #实际是调用了 __delitem__ 方法
当使用with … as … 语法时,需要在对应的类里试下 __ enter __ 和 __ exit __ 两个方法,这两个方法分别对应创建和销毁上下文
class Test:
def __enter__(self):
print('__enter__')
def __exit__(self, exc_type, exc_val, exc_tb):
print('__exit__')
t = Test()
with t as f: #此时调用 __enter__ 方法
pass #当执行完缩进代码块后调用 __exit__ 方法
class Test:
def __add__(self, other):
'''加,自加是 __iadd__ '''
pass
def __sub__(self, other):
'''减,自减是 __isub__ '''
pass
def __mul__(self, other):
'''乘,自乘是 __imul__ '''
pass
def __truediv__(self, other):
'''除,结果带小数,自除是 __itruediv__ '''
pass
def __floordiv__(self, other):
'''除,结果无小数,向下取整,自除是 __ifloordiv__ '''
pass
def __mod__(self, other):
'''取模,自取模是 __imod__'''
pass
def __pow__(self, power, modulo=None):
'''幂,自幂是 __ipow__ '''
pass
class Test:
def __lt__(self, other):
'''小于'''
pass
def __gt__(self, other):
'''大于'''
pass
def __eq__(self, other):
'''等于'''
pass
def __le__(self, other):
'''小于等于'''
pass
def __ge__(self, other):
'''大于等于'''
pass
def __ne__(self, other):
'''不等于'''
pass
class Test:
def __and__(self, other):
'''与'''
pass
def __or__(self, other):
'''或'''
pass
def __xor__(self, other):
'''异或'''
pass
def __lshift__(self, other):
'''左移'''
pass
def __rshift__(self, other):
'''右移'''
pass
如果实现迭代器(可迭代对象)
如果使用迭代器(可迭代对象)
class Test:
def __init__(self, num):
self.num=num
def __iter__(self):
return self
def __next__(self):
self.num += 1
if self.num >= 10:
raise StopIteration
else:
return self.num
t=Test(4)
for tx in t:
print(tx) # 5, 6, 7, 8, 9
# 检测对象是否实现了 __call__ 方法
callable(obj)
# 按照继承顺序去父类里找对应的方法和变量
# 如果是多继承,对父类的初始化需要使用未绑定方法
super()
# 返回对象的类名
type(obj)
# 检测对象是否为指定类的实例
isinstance(obj, Test)
# 检测两个类是否有继承关系
issubclass(cls1, cls2)
try:
逻辑代码块
except Exception as e:
当try中的代码遇到异常时,此处代码块会被执行
finally:
无论异常处理代码块是否执行,当try代码结束后都会执行此处代码,一般用于释放资源
如果try里调用了return,则finally代码会在return 前被执行
class MyException(Exception):
pass
# 必须要继承父类 Exception,在自定义类里可以用类变量或者实例变量记录此异常代表的错误信息
反射是通过字符串在对象或模块中进行增删改查成员的操作。
反射要解决的问题:当要执行的方法或者变量名以字符串形式存储在其他变量里时,可以通过此变量操作相应对象或模块里的方法或变量。
python 支持反射的4个方法
class Test:
def __init__(self, name, age):
self.name=name
self.age=age
def info(self):
return "{}-{}".format(self.name, self.age)
op_name=input("请输入操作名称:")
t=Test("aizhaoyu", 18)
if hasattr(t, op_name):
print("{} exists".format(op_name))
else:
print("{} doesn't exist".format(op_name))
exit(0)
op=getattr(t, op_name, None)
if callable(op):
print("{} is a method".format(op_name))
else:
print("{} is a variable".format(op_name))
new_value=input("重置变量{}:".format(op_name))
setattr(t, op_name, new_value)
print(getattr(t, op_name, None))
delattr(t, op_name)
print(getattr(t, op_name, None))
import socket
import select
# 和Linux C socket API基本一致
socket.socket()
setblocking()
bind()
listen()
connect()
close()
accept() # 返回connection
# connection session
send/sendall()
recv()
close()
# IO 复用,和Linux C IO 复用API基本一致
select.select() #方法
select.poll() #类
select.epool() #类