python 类和对象详解
2023年3月11日大约 3 分钟约 1022 字
python中一切皆对象
python中类
也是对象:
做为类来说,object是所有类的最顶层的基类(包括type)
做为对象来说,type生成了所有类,类
是type类
生成的对象(包括object)
type是对象而且本身也是类,父类是object。object对象是type类生成的。
type生成了object,同时type让object做为自己的父类。
总结的说:type生成类这个对象,object被类继承。
这里有一疑问:type是谁生成的?type是自己生成的,它自己把自己变成了一个对象,所以它可以把其他类变成了对象。
# type -> int -> 1
type(1)
type(int)
# type -> class -> object
class Student:
pass
stu = Student()
type(stu)
type(Student)
# 查看基类
print(Student.__bases__)
python对象的三个特征:
- 内存地址(id函数可查询)
- 类型
- None(全局唯一对象)
- 数值(整型、浮点、复数、布尔)
- 迭代类型(迭代器、生成器)
- 序列类型(列表、元组、字符串、字节码 等等)
- 映射类型(字典)
- 集合(set、frozenset)
- 上下文管理类型(with语句)
- 其他类型(模块、class和实例、函数和方法、代码、object对象、type类型、ellipsis省略号类型、notimplemented类型)
- 值
魔法函数
魔法函数是双下划线开头且结尾的函数。
魔法函数一览
非数学运算:
- 字符串表示
__repr__
__str__
- 集合、序列相关
__len__
__getitem__
__setitem__
__delitem__
__contains__
- 迭代相关
__iter__
__next__
- 可调用
__call__
- with上下文管理器
__enter__
__exit__
- 数值转换
__abs__
__bool__
__int__
__float__
__hash__
__index__
- 元类相关
__new__
__init__
- 属性相关
__getattr__
、__setattr__
__getattribute__
、__setattribute__
__dir__
- 属性描述符
__get__
、__set__
、__delete__
- 协程
__await__
、__aiter__
、__anext__
、__aenter__
、__aexit__
数学运算:
- 一元运算符
- neg(-)、pos(+)、abs
- 二元运算符
- lt(<)、 le <= 、 eq == 、 ne != 、 gt > 、 ge >=
- 算术运算符
- add + 、 sub - 、 mul * 、 truediv / 、 floordiv // 、 __ mod__ % 、 divmod divmod() 、 pow ** 或 pow() 、 round round()
- 反向算术运算符
- radd 、 rsub 、 rmul 、 rtruediv 、 rfloordiv 、 rmod 、 rdivmod 、 rpow
- 增量赋值算术运算符
- iadd 、 isub 、 imul 、 itruediv 、 ifloordiv 、 imod 、 ipow
- 位运算符
- invert ~ 、 lshift << 、 rshift >> 、 and & 、 or | 、 __ xor__ ^
- 反向位运算符
- rlshift 、 rrshift 、 rand 、 rxor 、 ror
- 增量赋值位运算符
- ilshift 、 irshift 、 iand 、 ixor 、 ior
可迭代的对象
直接循环对象会调用__getitem__()
class Company(object):
def __init__(self, employee_list):
self.employee = employee_list
def __getitem__(self, item):
return self.employee[item]
company = Company(['张三', '李四', '王五'])
company1 = company[:2]
for em in company:
print(em)
抽象基类(abc模块)
鸭子类型和魔法方法贯穿了整个python
抽象基类提供接口标准,本身不能被实例化
抽象基类使用原因:
- 需要强制某一个子类必须实现某些方法
- 在某些情况系统判定某个对象的类型
# 模拟一个抽象基类(推荐使用):
# 仅在调用方法的时候抛异常,不能在实例化的时候抛异常
class Animal():
def eat(self):
raise NotImplementedError
def run(self):
raise NotImplementedError
# 使用全局abc模块:
# 在实例化的时候抛异常
# 不推荐使用,因为比上面的逻辑复杂,用来学习
import abc
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod
def eat(self):
pass
@abc.abstractmethod
def run(self):
pass
# python内置的一些接口
# 可当做文档看
from collections.abc import *
多继承的查找顺序
python使用的是c3算法查找属性
正常的矩形继承时,使用的深度优先算法。菱形继承时,使用的广度优先算法。
使用DemoClass.__mro__
可查询查找顺序。
python不建议使用多继承,可能会照成逻辑混乱,推荐使用mixin模式
私有属性
类的私有属性使用双下划线__
开头的是私有属性,不能被外部访问。
对象的自省
dog = Dog()
# 仅查看该对象内的属性
dog.__dict__
# 动态修改对象的属性
dog.__dict__['sleep_time'] = 8
# 列出对象所有属性
dir(dog)
Animal
上下文管理器
修饰类:
class Sample:
def __enter__(self):
print('enter')
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print('exit')
def do_something(self):
print('doing something')
with Sample() as sample:
sample.do_something()
修饰函数:
import contextlib
@contextlib.contextmanager
def file_open(file_name):
print('file open')
yield {}
print('file end')
with file_open('abc.txt') as f_opened:
print('file processing')