10.18

属性和方法

        魔术方法

        Python中的魔术方法(Magic Methods)是一种特殊的方法,它们以双下划线开头和结尾,例如`__init__`,`__str__`,`__add__`等。这些方法允许您自定义类的行为,以便与内置Python功能(如+运算符、迭代、字符串表示等)交互。

常用的Python魔术方法

1. `__init__(self, ...)`: 初始化对象,通常用于设置对象的属性。

2. `__str__(self)`: 定义对象的字符串表示形式,可通过`str(object)`或`print(object)`调用。例如,您可以返回一个字符串,描述对象的属性。

3. `__repr__(self)`: 定义对象的“官方”字符串表示形式,通常用于调试。可通过`repr(object)`调用。

4. `__len__(self)`: 定义对象的长度,可通过`len(object)`调用。通常在自定义容器类中使用。

5. `__getitem__(self, key)`: 定义对象的索引操作,使对象可被像列表或字典一样索引。例如,`object[key]`。

6. `__setitem__(self, key, value)`: 定义对象的赋值操作,使对象可像列表或字典一样赋值。例如,`object[key] = value`。

7. `__delitem__(self, key)`: 定义对象的删除操作,使对象可像列表或字典一样删除元素。例如,`del object[key]`。

8. `__iter__(self)`: 定义迭代器,使对象可迭代,可用于`for`循环。

9. `__next__(self)`: 定义迭代器的下一个元素,通常与`__iter__`一起使用。

10. `__add__(self, other)`: 定义对象相加的行为,使对象可以使用`+`运算符相加。例如,`object1 + object2`。

11. `__sub__(self, other)`: 定义对象相减的行为,使对象可以使用`-`运算符相减。

12. `__eq__(self, other)`: 定义对象相等性的行为,使对象可以使用`==`运算符比较。

13. `__lt__(self, other)`: 定义对象小于其他对象的行为,使对象可以使用`<`运算符比较。

14. `__gt__(self, other)`: 定义对象大于其他对象的行为,使对象可以使用`>`运算符比较。

15. `__call__(self, other)` 是一个特殊的方法(也称为“魔法方法”),它允许一个对象像函数一样被调用。

封装 enclosure

        封装是指隐藏类的实现细节,让使用者不用关心这些细节;

        封装的目的是让使用者通过尽可能少的方法(或属性)操作对

Python的封装是假的(模拟的)封装

        强行访问私有:实例._类名__方法名()

私有属性和方法

        python类中以双下划线(`__`)开头,不以双下划线结尾的标识符为私有成员,私有成员只能使用方法来进行访问和修改

        以`__`开头的属性为类的私有属性,在子类和类外部无法直接使用

        以`__`开头的方法为私有方法,在子类和类外部无法直接调用

多态 polymorphic

        字面意思"多种状态"

        多态是指在有继承/派生关系的类中,调用基类对象的方法,实际能调用子类的覆盖方法的现象叫多态

状态:

        静态(编译时状态)

        动态(运行时状态)

多态说明:

        多态调用的方法与对象相关,不与类型相关

        Python的全部对象都只有"运行时状态(动态)", 没有"C++语言"里的"编译时状态(静态)"

方法重写

函数重写

        在自定义类内添加相应的方法,让自定义类创建的实例像内建对象一样进行内建函数操作

对象转字符串函数重写

str() 函数的重载方法:

`def __str__(self)`

如果没有 `__str__(self)` 方法,则返回repr(obj)函数结果代替

内建函数重写

__abs__ abs(obj) 函数调用

__len__ len(obj) 函数调用

__reversed__ reversed(obj) 函数调用

__round__ round(obj) 函数调用

运算符重载

        运算符重载是指让自定义的类生成的对象(实例)能够使用运算符进行操作

作用

        让自定义类的实例像内建对象一样进行运算符操作

        让程序简洁易读

        对自定义对象将运算符赋予新的运算规则

重载说明

        运算符重载方法的参数已经有固定的含义,不建议改变原有的意义

二元运算符重载方法格式

def __xxx__(self, other): ....

super函数

        是用于调用父类(超类)的一个方法。

        super()是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。

语法:

        在子类方法中可以使用super().add()调用父类中已被覆盖的方法

        可以使用super(Child, obj).myMethod()用子类对象调用父类已被覆盖的方法

super().__init__()

        `super().__init__()` 是 Python 中用于调用父类(基类)构造函数的一种方式。

它通常用于子类的构造函数中,以确保父类的构造函数被正确调用和初始化。

注释

Parent 类

定义了一个构造函数 `__init__()`,在构造函数中打印了一条消息,并初始化了一个属性 `parent_attribute`。

Child 类

继承自 `Parent` 类。

在其构造函数 `__init__()` 中,首先调用了 `super().__init__()`。这行代码会调用 `Parent` 类的构造函数,确保 `Parent` 类的初始化逻辑被执行。

然后打印了一条消息,并初始化了一个属性 `child_attribute`。

实例化 Child 类

创建 `Child` 类的实例时,首先执行 `Parent` 类的构造函数,打印 "Parent class constructor called",然后执行 `Child` 类的构造函数,打印 "Child class constructor called"。

Python迭代器与生成器

迭代器

什么是迭代器

        迭代器是访问可迭代对象的工具

        迭代器是指用 iter(obj) 函数返回的对象(实例)

        迭代器可以用next(it)函数获取可迭代对象的数据

迭代器函数iter和next
iter(iterable)

        从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象

next(iterator)

        从迭代器iterator中获取下一个记录,如果无法获取一下条记录,则触发 StopIteration 异常

迭代器说明

        迭代器只能往前取值,不会后退

        用iter函数可以返回一个可迭代对象的迭代器

迭代器的用途

        迭代器对象能用next函数获取下一个元素

生成器

什么是生成器

        生成器是在程序运行时生成数据,与容器不同,它通常不会在内存中保留大量的数据,而是现用现生成。

        yield 是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。

        跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

        每次使用 yield 语句生产一个值后,函数都将暂停执行,等待被重新唤醒。

        yield 语句相比于 return 语句,差别就在于 yield 语句返回的是可迭代对象,而 return 返回的为不可迭代对象。

        然后,每次调用生成器的 next() 方法或使用 for 循环进行迭代时,函数会从上次暂停的地方继续执行,直到再次遇到 yield 语句。

        生成器可以用算法动态的生成数据

生成器有两种
生成器函数

        含有yield 语句的函数是生成器函数,此函数调用回返回一个生成器对象,生成器也是可迭代对象

yield 语句的语法

yield 表达式

生成器表达式

语法:

( 表达式 for 变量 in 可迭代对象 [if 真值表达式]) ps:[] 内容代表可以省略

用推导式的形式创建一个生成器

python 函数式编程

定义:用一系列函数解决问题。

函数可以赋值给变量,赋值后变量绑定函数

允许将函数作为参数传入另一个函数

允许函数返回一个函数。

**总结**

什么时候使用函数式编程思想?

很多的逻辑或者说核心点是不变的,大多数就是一致的,这个时候我们就可以使用函数式编程思想,可以很好的去定位这个逻辑【函数 式编程思想相对于面向对象编程思想,它更接近于算法】。

函数式编程思想替代了面向对象思想?

如果需求中存在多个逻辑变化点时,可以使用类来进行,因为面向对象中存在继承、重写。而函数式编程思想则是将变化点提取到函数 中,实现简单的逻辑。

函数作为参数

将核心逻辑传入方法体,使该方法的适用性更广。

lambda 表达式

定义:是一种匿名函数

作用:

作为参数传递时语法简洁,优雅,代码可读性强。

随时创建和销毁,减少程序耦合度。

# 定义: 变量 = lambda 形参: 方法体 # 调用: 变量(实参)

形参没有可以不填

方法体只能有一条语句,且不支持赋值语句。

内置高阶函数

定义:将函数作为参数或返回值的函数。

        map(函数,可迭代对象)

使用可迭代对象中的每个元素调用函数,将返回值作为新可迭代对象元素;返回值为新可迭代对象。

        filter(函数,可迭代对象)

根据条件筛选可迭代对象中的元素,返回值为新可迭代对象。

        sorted(可迭代对象, key=函数, reverse=True)

排序,返回值为排序后的列表结果。

        max(可迭代对象, key = 函数)

根据函数获取可迭代对象的最大值。

        min(可迭代对象,key = 函数)

根据函数获取可迭代对象的最小值。

函数作为返回值

闭包 closure

        闭包是指引用了此函数外部嵌套函数的变量的函数

        闭包就是能够读取其他函数内部变量的函数。只有函数内部的嵌套函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数,同时这个函数又引用了外部的变量“。

        在本质上,闭包是将内部嵌套函数和函数外部的执行环境绑定在一起的对象。

必须满足以下三个条件

必须有一个内嵌函数

内嵌函数必须引用外部函数中变量

外部函数返回值必须是内嵌函数。

全局变量和局部变量的区别

全局变量

        一直存在,谁都可以访问和修改

局部变量

        只是在调用时存在,只能在函数内部进行访问和修改

闭包的优缺点

优点

1. 逻辑连续,当闭包作为另一个函数调用参数时,避免脱离当前逻辑而单独编写额外逻辑。

2. 方便调用上下文的局部变量。

3. 加强封装性,是第2点的延伸,可以达到对变量的保护作用。

注意点(缺点)

1. 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包

2. 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值

装饰器 decorators(专业提高篇)

什么是装饰器

        装饰器是一个函数,主要作用是来用包装另一个函数或类

装饰器的作用

        在不修改被装饰的函数的源代码,不改变被装饰的函数的调用方式的情况下添加或改变原函数的功能。

函数装饰器的语法

        def 装饰器函数名(fn): 语句块 return 函数对象 @装饰器函数名 <换行> def 被装饰函数名(形参列表): 语句块

用函数装饰器替换原函数myfun

def mydeco(fn): fn() print("装饰器函数被调用了,并返回了fx") def fx(): print("fx被调用了") # return fn() return fx @ mydeco def myfun(): print("函数myfun被调用") myfun() myfun()

实际上发生的

1. `myfun`函数作为参数传递给了`mydeco`装饰器。

2. 在`mydeco`内部,首先调用了`fn()`,即此时调用了`myfun`函数,产生了输出:"函数myfun被调用"。

3. 接着,打印了"装饰器函数被调用了,并返回了fx"。

4. 然后,`mydeco`装饰器返回了新的函数`fx`。

基本装饰器

        有参数的函数装饰器(在myfunc外加了一层)

带参数的装饰器

        带参数的装饰器需要三层函数,def wrapper(args, kwargs) 传入的是被修饰的函数的参数。

装饰器链
类装饰器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值