Python学习笔记

基本数据类型

基本数据类型:int(整型),float(浮点型),str(字符串),list(列表),tuple(元组),set(集合),dict(字典),bool(布尔)

可变序列:列表,集合,字典
不可变序列:字符串,元组
可迭代类型:字符串,列表,元组,集合,字典

整型

浮点型

字符串

列表

元组

集合

字典

字典键值互换

d = {1: 'a', 2: 'b', 3: 'c'}
# 方法一
print(dict(zip(d.values(), d.keys()))) # {'a': 1, 'b': 2, 'c': 3}

# 方法二
print({v: k for k, v in d.items()}) # {'a': 1, 'b': 2, 'c': 3}

布尔

其他

运算符

流程控制

顺序结构

a = 1
b = 2
c = 3

print(a)
print(b)
print(c)

选择结构

if
n = 100
if n >= 10:
    print('n 大于等于 10')
if n >= 100:
    print('n 大于等于 100')
if n >= 1000:
    print('n 大于等于 1000')
if-else
n = 1
if n > 100:
    print('n 大于 100')
else:
    print('n 小于等于 100')
if-elif-else
n = 100
if n >= 10:
    print('n 大于等于 10')
elif n >= 100:
    print('n 大于等于 100')
elif n >= 1000:
    print('n 大于等于 1000')
else:
    print('n 小于 10')
三目运算符
# if-else判断奇数偶数
n = 100
what_number = '偶数' if not n % 2 else '奇数'
print(what_number)

# and-or实现判断奇数偶数
n = 100
what_number = n % 2 == 0 and '偶数'or '奇数'
print(what_number)

循环结构

for
# 计算1加到100的和
n = 0
for i in range(101):
    n += i
    
print(n)
for-else
# 计算1加到100的和
n = 0
for i in range(101):
    n += i
    # break
else:
    print('no break,I will execute!')

print(n)
while
# 计算1加到100的和
i,n = 0,0
while i <= 100:
    n += i
    i += 1

print(n)
while-else
# 计算1加到100的和
i,n = 0,0
while i <= 100:
    n += i
    i += 1
    # break
else:
    print('no break,I will execute!')

print(n)

推导式

列表推导式

# 九九乘法表
list_derivation = ['%dx%d=%d'%(j,i,i*j) for i in range(1,10) for j in range(1,i+1)]

集合推导式

# 生成100以内的偶数集合
set_derivation = {i for i in range(100) if i%2==0}

字典推导式

# 生成128以内的ascii码
dict_derivation = {chr(i):i for i in range(128)}

元组推导式(生成器)

# 构造生成100000000以内数的生成器
generator = (i for i in range(100000000))

函数

函数参数

必选参数
def f(a,b,c):
    print(a,b,c)

f(1,2,3)
位置参数
def f(*args):
    print(*args)
    print(args)

f(1,2,3)
f(*[1,2,3])
关键字参数
def f(**kwargs):
    # print(**kwargs) # error
    print(kwargs)

f(a=1,b=2,c=3)
f(**{'a':1,'b':2,'c':3})
默认参数
def f(a=1,b=2,c=None):
    print(a,b,c)

f()
f(c=3)
/
# 声明位置参数传参
def f(a,/,b,c):
    print(a,b,c)

f(1,b=2,c=3)
  • /号之前只能使用位置参数
*
# 声明关键字参数传参
def f(a,b,*,c,d=2,e):
    print(a,b,c,d,e)

f(1,2,c=3,d=4,e=5)
  • *号之后只能使用关键字参数
/ *
# 声明位置参数和关键字参数传参
def f(a, /, *, b, c):
	print(a,b,c)

f(1,b=2,c=3) # 限制只能以这种方式传参
  • 同时限制位置参数和关键字参数的传参方式

变量作用域

x = 0
def outer():
    a = 0
    def inner1():
        nonlocal a
        a = 1
        print(a)

    def inner2():
        global a,x
        x = 123
        a = 2
        print(a)

    inner1()
    print(a)

    inner2()
    print(a)

outer()
print(x)
print(a,id(a))
print(globals(),id(globals()['a']))
  • global:块内声明参数为全局参数,使其可以在被声明的块内被修改。
  • nonlocal:声明参数为外层参数,使其可以被内层代码修改。

匿名函数

# 普通函数
# def square(x):
#     return x**2

# 匿名函数
square = lambda x:x**2
print(square(10))

内置函数

数学函数:abs pow divmod
可迭代类型布尔判断函数:all any
代码执行函数:eval exec
实例属性操作函数:getattr setattr hasattr delattr
统计函数:min max sum
高阶函数:filter map
进制转换函数:bin oct hex
编码数值字符转换函数:chr ord
输出可打印形式字符串函数:repr ascii
输入输出函数:input print
类型函数:bool complex int float str list tuple set frozenset dict bytes bytearray
类和对象相关函数:id super isinstance issubclass dir type object
变量空间:globals locals vars
序列操作函数:sorted reversed
其他:memoryview compile breakpoint callable format hash help iter next open round slice enumerate range zip property staticmethod __import__
具体使用操作

压包、解包

可迭代对象都可以解包

# 字符串
a,b,c = 'abc'

# 列表
a,b,c = ['a','b','c']

# 元组
a,b,c = (1,2,3)

# 集合
a,b,c = {1,2,3}

# 字典
a,b,c = {'a':1,'b':2,'c':3}

# 其他可迭代对象
a,b,c = (i for i in range(1,4))
a,b,c = {'a':1,'b':2,'c':3}.items()
a,b,c = enumerate(['a','b','c'])
a,b,c = reversed(['c','b','a'])
...

解包合并可迭代对象

# *解包
a = [1,2,3]
b = [*a,4,5,6]

# **解包
a = {'a':1,'b':2,'c':3}
b = {**a,'d':4,'e':5,'f':6}

解包传递参数

# *解包
def f1(a,b,c):
    print(a,b,c)

f1(*[1,2,3])

# **解包
def f2(b,a,c):
    print(a,b,c)

f2(**{'a':1,'b':2,'c':3})

# 传递参数时解包,接收参数时压包
def f3(*args,**kwargs):
    print(args,kwargs)

f3(*[1,2,3],**{'a':1,'b':2,'c':3})
  • f(*[1,2,3])等价于f(1,2,3)
  • f(**{'a':1,'b':2,'c':3})等价于f(a=1,b=2,c=3)
  • 压包获取的数据args元组kwargs字典
  • 压包可以看做作是将多个参数存到元组或字典中,解包则是将元组或字典中的数据拿出来。

闭包、装饰器

闭包

def outer(func_name):
    print('outer开始执行了')

    def inner1():
        print('inner1执行了')

    def inner2():
        print('inner2执行了')

    print('outer执行完成了')
    if func_name == 'inner1':
        return inner1
    else:
        return inner2

outer('inner2')()

装饰器

原理
def hello():
    print('123')
    
def decorator(f):
    return f()
    
hello = decorator(hello)
# 等价于下面语法糖写法
@decorator
def hello():
    print('123')
函数装饰器
def decorator(f):
    def inner(*args, **kwargs):
        print('函数开始执行')
        f(*args, **kwargs)
        print('函数执行完成')

    return inner


@decorator
def f():
    print('hello')


f()
类装饰器
class Decorator:
    def __init__(self, f):
        self.f = f

    def __call__(self, *args, **kwargs):
        print('函数开始执行')
        self.f(*args, **kwargs)
        print('函数执行完成')


@Decorator
def f():
    print('hello')


f()
不带参数的装饰器
# 不带参数的装饰器
def outer(f):
    def inner(*args, **kwargs): # 回调函数参数声明
        print(args,kwargs)
        param = "I'm the param of f function."
        f(param)
    return inner

# 闭包写法
# def f(param): # 原函数参数声明
#     print(param)
#     print('hello')
#
# f = outer(f)(1,2,3,4,5,whoami="I'm the param of callback function.")

# 语法糖写法
@outer
def f(param): # 原函数参数声明
    print(param)
    print('hello')

f(1,2,3,4,5,whoami="I'm the param of callback function.")
带参数的装饰器

装饰器函数,包装函数带参数

# 带参数的装饰器
def outer(decorator_param=None): # 装饰器函数参数声明
    def wrapper(f):
        def inner(*args, **kwargs): # 包装函数参数声明
            print(decorator_param)
            print(args,kwargs)
            param = "I'm the param of f function."
            f(param)
        return inner
    return wrapper

# 闭包写法
# def f(param): # 原函数参数声明
#     print(param)
#     print('hello')
#
# f = outer('a')(f)(1,2,3,4,5)

# 语法糖写法 
@outer(decorator_param="I'm the param of decorator.")
def f(param): # 原函数参数声明
    print(param)
    print('hello')

f(1,2,3,4,5,whoami="I'm the param of callback function.")

装饰器函数带参数,包装函数不带参数

def outer(decorator_param=None):
    def inner(f):
        print(decorator_param)
        return f
    return inner

# 闭包写法
# def index():
#     print('hello')
# 
# index = outer('/index')(index)

# 语法糖写法
@outer('/index')
def index():
    print('hello')
函数装饰器的使用
from functools import wraps


# 装饰函数(不带参数)
def function_decorator(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        # do something here
        print(args, kwargs, 'in function_decorator.wrapper')
        return func(*args, **kwargs)
    return wrapper


# 装饰函数(带参数)
def function_decorator_with_params(a, b=None):
    def wrapper(func):
        @wraps(func)
        def inner(*args, **kwargs):
            # do something here
            print(a, b, 'in function_decorator_with_params.wrapper.inner')
            print(args, kwargs, 'in function_decorator_with_params.wrapper.inner')
            return func(*args, **kwargs)
        return inner
    return wrapper


# 装饰方法(不带参数)
def method_decorator(func):
    @wraps(func)
    def wrapper(self, *args, **kwargs):
        # do something here
        print(self, args, kwargs, 'in method_decorator.wrapper')
        return func(self, *args, **kwargs)
    return wrapper


# 装饰方法(带参数)
def method_decorator_with_params(a, b=None):
    def wrapper(func):
        @wraps(func)
        def inner(self, *args, **kwargs):
            # do something here
            print(a, b, 'in method_decorator_with_params.wrapper.inner')
            print(self, args, kwargs, 'in method_decorator_with_params.wrapper.inner')
            return func(self, *args, **kwargs)
        return inner
    return wrapper


# 装饰类(不带参数)
def class_decorator(cls):
    @wraps(cls)
    def wrapper(*args, **kwargs):
        print(args, kwargs, 'in class_decorator.wrapper')
        return cls(*args, **kwargs)
    return wrapper


# 装饰类(带参数)
def class_decorator_with_params(a, b=None):
    def wrapper(cls):
        @wraps(cls)
        def inner(*args, **kwargs):
            print(a, b, 'in class_decorator_with_params.wrapper.inner')
            print(args, kwargs, 'in class_decorator_with_params.wrapper.inner')
            return cls(*args, **kwargs)
        return inner
    return wrapper


@function_decorator
def f1(*args, **kwargs):
    print(args, kwargs, 'in f1')


@function_decorator
def f2(*args, **kwargs):
    print(args, kwargs, 'in f2')


# @class_decorator
@class_decorator_with_params(1, 2)
class MyClass:

    def __init__(self, *args, **kwargs):
        pass

    @method_decorator
    def method1(self, *args, **kwargs):
        print(args, kwargs, 'in method')

    @method_decorator_with_params(1, 2)
    def method2(self, *args, **kwargs):
        print(args, kwargs, 'in method')


if __name__ == '__main__':
    # 不带参数 装饰函数 装饰器
    f1(1, y=2)
    # 带参数 装饰函数 装饰器
    f2(1, y=2)

    # 带参和不带参的 装饰类 装饰器
    myclass = MyClass(a=1, b=2)

    # 不带参数 装饰方法 装饰器
    myclass.method1(1, 2)
    # 带参数的 装饰方法 装饰器
    myclass.method2(1, 2)
  • 函数装饰器的使用对象:函数,方法,类。
  • 函数装饰器的使用场景:传参,校验,绑定。

定义类和实例化

# 定义类
class Cat:
    # 魔术方法
    def __init__(self, name, color):
        # 实例属性
        self.name = name
        self.color = color
    
    # 实例方法
    def eat(self, food):
        print('吃' + food)


# 实例化
cat = Cat('汤姆', '黄色')
# 判断cat是否是Cat的实例
print(isinstance(cat, Cat))
# 调用实例方法
cat.eat('鱼')
  • isinstance:判断cat是否是Cat的实例。

类属性和实例属性

class MyClass:
    # 定义类属性
    a = 1

    def __init__(self, c):
        # 定义实例属性
        self.b = 2
        self.c = c


myclass = MyClass(3)

# 类调用类属性
print(MyClass.a)

# 实例调用类属性
print(myclass.a)

# 实例调用实例属性
print(myclass.b)
print(myclass.c)

类方法、静态方法、实例方法

class MyClass:

    @classmethod
    def method1(cls):
        print('类方法')

    @staticmethod
    def method2():
        print('静态方法')

    def method3(self):
        print('实例方法')

# 实例化
myclass = MyClass() # myclass是MyClass类的一个实例(对象)。

# 类方法调用
MyClass.method1()
myclass.method1()
# 静态方法调用
MyClass.method2()
myclass.method2()
# 实例方法调用
myclass.method3()
  • @classmethod装饰的方法是类方法,可以通过类或实例调用。
  • @staticmethod装饰的方法是静态方法,可以通过类或实例调用。
  • 实例方法只能通过实例调用。

方法属性化

property装饰器写法

class Person:

    def __init__(self, name, age):
        self.name = name
        self._age = age

    @property
    def age(self):
        pass

    @age.getter
    def age(self):
        print('age被获取了')
        return self._age

    @age.setter
    def age(self, value):
        if isinstance(value, int):
            print('age被重新赋值了')
            self._age = value
        else:
            raise TypeError('类型错误!')

    @age.deleter
    def age(self):
        print('age被删除了')
        del self._age


person = Person('jack', 10)

print(person.age)

person.age = 12

print(person.age)

del person.age

property类写法

class Person:

    def __init__(self, name, age):
        self.name = name
        self._age = age

    def age_get(self):
        print('age被获取了')
        return self._age

    def age_set(self, value):
        if isinstance(value, int):
            print('age被重新赋值了')
            self._age = value
        else:
            raise TypeError('类型错误!')

    def age_del(self):
        print('age被删除了')
        del self._age

    age = property(age_get, age_set, age_del)


person = Person('jack', 10)

print(person.age)

person.age = 12

print(person.age)

del person.age
  • @property装饰的是需要属性化的方法,该方法定义了属性的获取操作,相当于 @xxx.getter。
  • @xxx.getter装饰的方法定义了属性的获取操作。
  • @xxx.setter装饰的方法定义了属性的赋值操作。
  • @xxx.deleter装饰的方法定义了属性的删除操作。

描述器

基本使用

class Value:

    def __init__(self):
        self.v = None

    def __get__(self, instance, owner):
        print('get', instance, owner)
        return self.v

    def __set__(self, instance, value):
        print('set', instance, value)
        self.v = value

    def __delete__(self, instance):
        print('delete', instance)
        del self.v


class MyClass:
    value = Value()


myclass = MyClass()

print(myclass.value)

myclass.value = 1

print(myclass.value)

del myclass.value

实现property

class property:

    def __init__(self, fget=None, fset=None, fdel=None, doc=None):
        self.fget = fget
        self.fset = fset
        self.fdel = fdel
        self.__doc__ = doc

    def __get__(self, instance, owner):
        return self.fget(instance)

    def __set__(self, instance, value):
        return self.fset(instance, value)

    def __delete__(self, instance):
        return self.fdel(instance)

    def getter(self, fget):
        return type(self)(fget, self.fset, self.fdel)

    def setter(self, fset):
        return type(self)(self.fget, fset, self.fdel)

    def deleter(self, fdel):
        return type(self)(self.fget, self.fset, fdel)

实现staticmethod

class staticmethod:

    def __init__(self, func):
        self.func = func

    def __get__(self, obj, objtype=None):
        return self.func

实现classmethod

class classmethod:

    def __init__(self, func):
        self.func = func

    def __get__(self, instance, owner):
        return lambda *args, **kwargs: self.func(owner, *args, **kwargs)

魔术方法

基本的魔法方法

__new__(cls[, ...])	创建对象的方法,当通过类去创建对象时就是调用__new__方法去创建的
__init__(self[, ...])	初始化方法,当实例被创建的时候调用的初始化方法
__del__(self)	析构方法,当实例被销毁的时候调用的方法
__call__(self[, args...])	允许一个类的实例像函数一样被调用:x(a, b) 调用 x.__call__(a, b)
__repr__(self)	定义当被 repr() 调用时的行为
__str__(self)	定义当被 str() 调用时的行为
__bytes__(self)	定义当被 bytes() 调用时的行为
__hash__(self)	定义当被 hash() 调用时的行为
__bool__(self)	定义当被 bool() 调用时的行为,应该返回 TrueFalse
__format__(self, format_spec)	定义当被 format() 调用时的行为

属性相关的魔法方法

__getattr__(self, name)	定义当用户试图获取一个不存在的属性时的行为,__getattribute__找不到属性时触发。
__getattribute__(self, name)	定义当该类的属性被访问时的行为,self.属性名时触发。
__setattr__(self, name, value)	定义当一个属性被设置时的行为
__delattr__(self, name)	定义当一个属性被删除时的行为
__dir__(self)	定义当 dir() 被调用时的行为
__get__(self, instance, owner)	定义当描述符的值被取得时的行为
__set__(self, instance, value)	定义当描述符的值被改变时的行为
__delete__(self, instance)	定义当描述符的值被删除时的行为

上下文管理器

__enter__(self)	定义当使用 with 语句进入上下文管理器执行的方法 ,__enter__ 的返回值被 with 语句的目标或者 as 后的名字绑定
__exit__(self, exc_type, exc_value, traceback)with中的代码块执行完毕后调用的方法。一般被用来处理异常,清除工作或者做一些代码块执行完毕之后的日常工作

容器类型数据相关

__len__(self)	定义当被 len() 调用时的行为(返回容器中元素的个数)
__getitem__(self, key)	定义获取容器中指定元素的行为,相当于 self[key]
__setitem__(self, key, value)	定义设置容器中指定元素的行为,相当于 self[key] = value
__delitem__(self, key)	定义删除容器中指定元素的行为,相当于 del self[key]
__iter__(self)	定义当迭代容器中的元素的行为
__reversed__(self)	定义当被 reversed() 调用时的行为
__contains__(self, item)	定义当使用成员测试运算符(innot in)时的行为

比较运算符

__lt__(self, other)	定义小于号的行为:x < y 调用 x.__lt__(y)
__le__(self, other)	定义小于等于号的行为:x <= y 调用 x.__le__(y)
__eq__(self, other)	定义等于号的行为:x == y 调用 x.__eq__(y)
__ne__(self, other)	定义不等号的行为:x != y 调用 x.__ne__(y)
__gt__(self, other)	定义大于号的行为:x > y 调用 x.__gt__(y)
__ge__(self, other)	定义大于等于号的行为:x >= y 调用 x.__ge__(y)

算术运算符

__add__(self, other)	定义加法的行为:+
__sub__(self, other)	定义减法的行为:-
__mul__(self, other)	定义乘法的行为:*
__truediv__(self, other)	定义真除法的行为:/
__floordiv__(self, other)	定义整数除法的行为://
__mod__(self, other)	定义取模算法的行为:%
__divmod__(self, other)	定义当被 divmod() 调用时的行为
__pow__(self, other[, modulo])	定义当被 power() 调用或 ` 运算时的行为
__lshift__(self, other)	定义按位左移位的行为:<<
__rshift__(self, other)	定义按位右移位的行为:>>
__and__(self, other)	定义按位与操作的行为:&
__xor__(self, other)	定义按位异或操作的行为:^
__or__(self, other)	定义按位或操作的行为:|

反运算

__radd__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rsub__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rmul__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rtruediv__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rfloordiv__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rmod__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rdivmod__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rpow__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rlshift__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rrshift__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rand__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__rxor__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)
__ror__(self, other)	(与上方相同,当左操作数不支持相应的操作时被调用)

增量赋值运算

__iadd__(self, other)	定义赋值加法的行为:+=
__isub__(self, other)	定义赋值减法的行为:-=
__imul__(self, other)	定义赋值乘法的行为:*=
__itruediv__(self, other)	定义赋值真除法的行为:/=
__ifloordiv__(self, other)	定义赋值整数除法的行为://=
__imod__(self, other)	定义赋值取模算法的行为:%=
__ipow__(self, other[, modulo])	定义赋值幂运算的行为:`=
__ilshift__(self, other)	定义赋值按位左移位的行为:<<=
__irshift__(self, other)	定义赋值按位右移位的行为:>>=
__iand__(self, other)	定义赋值按位与操作的行为:&=
__ixor__(self, other)	定义赋值按位异或操作的行为:^=
__ior__(self, other)	定义赋值按位或操作的行为:|=

一元操作符

__pos__(self)	定义正号的行为:+x
__neg__(self)	定义负号的行为:-x
__abs__(self)	定义当被 abs() 调用时的行为
__invert__(self)	定义按位求反的行为:~x

类型转换

__complex__(self)	定义当被 complex() 调用时的行为(需要返回恰当的值)
__int__(self)	定义当被 int() 调用时的行为(需要返回恰当的值)
__float__(self)	定义当被 float() 调用时的行为(需要返回恰当的值)
__round__(self)	定义当被 round() 调用时的行为(需要返回恰当的值)
__index__(self)	1. 当对象是被应用在切片表达式中时,实现整形强制转换
2. 如果你定义了一个可能在切片时用到的定制的数值型,你应该定义 __index__
3. 如果 __index__ 被定义,则 int 也需要被定义,且返回相同的值

访问权限

受保护属性,私有属性

class A:
    def __init__(self):
        # 受保护属性
        self._a = 1
        # 私有属性
        self.__b = 2


class B(A):
    def __init__(self):
        super().__init__()
        print(self._a)
        # print(self.__b) # AttributeError: 'B' object has no attribute '_B__b'


a = A()

print(a._a)
# print(a.__b) # AttributeError: 'A' object has no attribute '__b'

b = B()
  • 受保护属性可以在类外部或子类中访问。
  • 私有属性不可以在类外部或子类中访问(一般情况)。

受保护方法,私有方法

class A:

    def _method(self):
        print('受保护方法')

    def __method(self):
        print('私有方法')


class B(A):
    def __init__(self):
        self._method()
        # self.__method() # AttributeError: 'B' object has no attribute '_B__method'


a = A()

a._method()
# a.__method() # AttributeError: 'A' object has no attribute '__method'

b = B()
  • 受保护方法可以在类外部或子类中访问。
  • 私有方法不可以在类外部或子类中访问(一般情况)。

访问私有属性和方法

class A:

    def __init__(self):
        self.__x = 1

    def __method(self):
        print('私有方法')


class B(A):
    def __init__(self):
        super().__init__()
        print(self._A__x)
        self._A__method()


b = B()
print(b._A__x)
b._A__method()
  • 一般情况下私有方法和私有变量不可以在类外部或子类中访问,但是可以通过实例._类名__变量名进行访问。

限定成员变量

__slots__的作用

from weakref import ref


class A:
    __slots__ = ('x', 'y')

    def __init__(self):
        self.x = 1
        self.y = 2
        # self.z = 3 # AttributeError: 'A' object has no attribute 'z'


a = A()
# print(a.__dict__) # AttributeError: 'A' object has no attribute '__dict__'
# a = ref(a) # TypeError: cannot create weak reference to 'B' object
  • __slots__允许我们声明并限定成员变量,并拒绝类创建__dict__和__weakref__属性以节约内存空间。

允许创建__dict__和__weakref__

from weakref import ref


class B:
    __slots__ = ('__dict__', '__weakref__', 'x')


b = B()
b.x, b.y = 1, 2
print(b.x)  # 1
# 获取__dict__字典
print(b.__dict__)  # {'y': 2}
# 获取弱引用对象
b = ref(b)
  • __slots__中未定义的变量将存储在__dict__中。

继承

单继承

class A:
    x = 1

    def __init__(self):
        self.y = 2

    def method(self):
        print('method in A')


class B(A):
    pass


print(issubclass(B, A))

b = B()
# 调用父类中的类属性
print(b.x)
# 调用父类中的实例属性
print(b.y)
# 调用父类中的方法
b.method()
  • issubclass:判断B是否是A的子类。

多继承

class A:
    x = 1

    def method(self):
        print('method in A')


class B:
    x = 2

    def method(self):
        print('method in B')


class C(A, B):
    pass


c = C()

print(c.x)  # 1

c.method()  # method in A
  • 继承的父类中具有相同的属性或方法时,多继承优先继承左边类的属性或方法。

菱形继承(钻石继承)

class A:
    def __init__(self):
        print('A')


class B(A):
    def __init__(self):
        super().__init__()
        print('B')


class C(A):
    def __init__(self):
        super().__init__()
        print('C')


class D(B, C):
    def __init__(self):
        super().__init__()
        print('D')


#   A
#  / \
# B   C
#  \ /
#   D
d = D()
# A
# C
# B
# D
print(D.__mro__)
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
  • 通过类名.__mro__查看方法解析顺序。

经典类和新式类的类继承的顺序

class A:
    def method(self):
        print('method in A')


class B(A):
    pass

class C(A):
    def method(self):
        print('method in C')


class D(B, C):
    pass

#   A
#  / \
# B   C
#  \ /
#   D


# Python2.x 区分经典类和新式类
# Python3.x 不区分经典类和新式类(默认继承object) 所以默认是新式类,使用的是广度优先搜索。
d = D()
# 不继承object 经典类 深度优先搜索 D -> B -> A -> C
d.method() # method in A

# 继承object   新式类 广度优先搜索 D -> B -> C -> A
d.method() # method in C
  • Python2.x 区分经典类和新式类,经典类使用的是深度优先搜索新式类使用的是广度优先搜索
  • Python3.x 不区分经典类和新式类(默认继承object) 所以默认是新式类,使用的是广度优先搜索。

多态

多态

class Animal:
    def talk(self):
        pass


class Cat(Animal):
    def talk(self):
        print('喵喵~~')


class Dog(Animal):
    def talk(self):
        print('汪汪~~')
  • 多态指的是一类事物有多种形态。

多态性

class Animal:
    def talk(self):
        pass


class Cat(Animal):
    def talk(self):
        print('喵喵~~')


class Dog(Animal):
    def talk(self):
        print('汪汪~~')


def talk(obj):
    obj.talk()


if __name__ == '__main__':
    cat = Cat()
    dog = Dog()

    for animal in [cat, dog]:
        talk(animal)
  • 多态性是指在不考虑实例类型的情况下使用实例。

鸭子类型(duck typing)

class Duck:
    def speak(self):
        print('嘎嘎~~')


class Cat:
    def speak(self):
        print('喵喵~~')


class Dog:
    def speak(self):
        print('汪汪~~')


def speak(obj):
    obj.speak()


if __name__ == '__main__':
    duck = Duck()
    cat = Cat()
    dog = Dog()

    speak(duck)
    speak(cat)
    speak(dog)
  • 实例之间可以没有任何关系,但是具有相同的方法。

type,object

可迭代对象

可迭代对象(iterable)

可迭代对象

a = '123'

for i in a:
    print(i)
  • 可以使用for遍历取值的都是可迭代对象。

内置可迭代对象

from collections.abc import Iterable

# 字符串
print(isinstance(str(), Iterable))
# 列表
print(isinstance(list(), Iterable))
# 元组
print(isinstance(tuple(), Iterable))
# 集合
print(isinstance(set(), Iterable))
# 字典
print(isinstance(dict(), Iterable))
# 字节
print(isinstance(bytes(), Iterable))
# 字节数组
print(isinstance(bytearray(), Iterable))
  • 内置可迭代对象:str list tuple set dict bytes bytesarray

自定义可迭代对象

from collections.abc import Iterable


# 迭代器实现可迭代对象
class A:

    def __iter__(self):
        # __iter__返回一个迭代器
        return iter([1, 2, 3, 4, 5])


# 生成器实现可迭代对象
class B:

    def __iter__(self):
        # __iter__返回一个生成器
        for i in range(1, 6):
            yield i


# 迭代器和生成器都是可迭代对象
print(isinstance(A(), Iterable))  # True
print(isinstance(B(), Iterable))  # True
  • 如果一个类实现了__iter__方法,那么这个类的实例就是一个可迭代对象。
  • __iter__方法需要返回一个迭代器或生成器对象。

迭代器(iterator)

迭代器

a = [1,2,3]
print(type(a)) # <class 'list'>

for i in a:
    print(i)

for i in a:
    print(i)
# 1
# 2
# 3
# 1
# 2
# 3

b = iter([1,2,3])
print(type(b)) # <class 'list_iterator'>

for i in b:
    print(i)

for i in b:
    print(i)
# 1
# 2
# 3
  • 可迭代对象可以重复迭代,而生成器对象不可以重复迭代。

生成器(generator)

生成器

# 表达式形式
a = (i for i in range(1,6))


# 函数形式
def f():
    for i in range(1,6):
        yield i

b = f()


print(type(a)) # <class 'generator'>
print(type(b)) # <class 'generator'>
  • 生成器有表达式函数形式,使用这两种形式构造的生成器都可以生成一个生成器对象

自定义生成器

class MyGenerator:

    def __init__(self):
        self.n = 0
        self.max = 5

    def __iter__(self):
        return self

    def __next__(self):
        while self.n < self.max:
            self.n += 1
            return self.n

        raise StopIteration

generator = MyGenerator()
# 打印数字1-5
for i in generator:
    print(i)
  • 一个类只有实现了__iter__和__next__方法,类的实例才具有生成器的特性。

  • for循环的每一轮迭代都会调用对象的__next__方法,直到抛出StopIteration异常循环才会停止。

yield和yield from的区别

class MyGenerator:

    def __init__(self):
        self.n = 0
        self.max = 5

    def __iter__(self):
        return self

    def __next__(self):
        self.n += 1
        while self.n <= self.max:
            return self.n

        raise StopIteration


generator = MyGenerator()

def get_data1():
    yield from generator

def get_data2():
    for i in generator:
        yield i

for i in get_data1():
    print(i)
    
for i in get_data2():
    print(i)
  • yield from generator 等价于 for i in generator:yield i

迭代器和生成器的区别

# 定义迭代器a
a = iter([1,2,3,4,5])
# 定义生成器b
b = (i for i in range(1,6))

print(type(a)) # <class 'list_iterator'>
print(type(b)) # <class 'generator'>

# 迭代器a迭代数据
print(next(a))
print(next(a))
print(next(a))
print(next(a))
print(next(a))

# 生成器b生成数据
print(next(b))
print(next(b))
print(next(b))
print(next(b))
print(next(b))

# 迭代完数据继续迭代会报错StopIteration
print(next(a))

# 生成完所有数据继续生成会报错StopIteration
print(next(b))
  • 迭代器和生成器都是可迭代对象。
  • 可迭代对象是一个抽象的概念,能够使用for迭代的对象都可以叫做可迭代对象。

文件、IO

文件

基本操作

# 打开文件
file = open('new.txt', 'w')
# 写入abc
file.write('abc')
# 写入def
file.writelines(['d','e','f','\n','1','2','3','4','5'])
# 关闭文件
file.close()


file = open('new.txt', 'r')
# 读取文件1个字节内容
# print(file.read(1))
# 读取文件全部内容
# print(file.read())

# 读取文件1个字节内容
# print(file.readline(1))
# 读取文件1行的内容(包括\n)
# print(file.readline())

# 读取文件以列表的形式(\n包括\n之前的字符串为列表中的一个元素)
print(file.readlines())
# 关闭文件
file.close()
  • 打开文件:open
  • 关闭文件:close
  • 写文件:write writelines
  • 读文件:read readline readlines

IO

import io

# 定义字符串缓冲区
a = io.StringIO()
# 字符串缓冲区写入
a.write('123')
a.writelines(['a','b','c'])
# 字符串缓冲区读取
print(a.getvalue())

# 定义字节缓冲区
b = io.BytesIO()
# 字节缓冲区写入
b.write(b'123')
b.writelines([b'a',b'b',b'c'])
# 字节缓冲区读取
print(b.getvalue())

异常

内置异常

内置异常

捕获异常

try:
    # raise IndexError
    a = [1,2,3]
    b = a[3]

    # raise KeyError
    # a = {}
    # b = a['1']

    # raise NameError
    # a = b

    # raise Exception
    # raise Exception

    # no error
    # pass
except IndexError as e:
    print('[×] IndexError say:',e)
except KeyError as e:
    print('[×] KeyError say:',e)
except NameError as e:
    print('[×] NameError say:',e)
except Exception as e:
    # I can catch any error
    print('[×] Exception say:',e)
else:
    print('[√] else say: No error I will execute')
finally:
    print('[√] finally say: Anyway I will execute')

抛出异常

raise

raise Exception

raise A from B

raise Exception from None
raise Exception from e
raise Exception from IndexError
  • 抛出异常A的原因是B

自定义异常

# 定义异常类
class MyException(Exception):

    def __init__(self, msg):
        super().__init__(msg)

# 捕获异常类
try:
    raise MyException('发生错误')
except MyException as e:
    print(e)

包和模块

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值