九、Python高阶语法

一、枚举

1.枚举类的特点

1. Python枚举作为一个类存在,使用它需要首先导入枚举模块,然后继承并自定义需要的​​枚举类​​;

2. 导入枚举模块可以是​​Enum​​(枚举值可以是任意类型),也可以是IntEnum(枚举值只能是整型);

3. 枚举类不允许存在相同的标签;但是允许不同标签的枚举值相同,这样后者相当于前者别名;

4. 不同的枚举类型,即使枚举名和枚举值都一样,比较结果也是False

2.定义枚举类

定义枚举类,需要在类的参数中,继承父类Enum

九、Python高阶语法_环境变量

3.获取枚举类型、名字、值、遍历

from enum import Enum,IntEnum,unique
# 定义枚举类,需要在类的参数中,继承父类Enum
class VIP(Enum):
    # 定义多个常量
    YELLOW = 1
    GREEN = 2
    BLACk = 3
    RED = 4
    
class Common():
    YELLOW = 1
    
# 获取枚举类型
print(VIP.GREEN)
print(type(VIP['GREEN']))   
   
# 获取枚举的名字
print(VIP.GREEN.name)

# 获取枚举的值
print(VIP.GREEN.value)

# 遍历枚举
for x in VIP:
    print(x)

结果

VIP.GREEN
<enum 'VIP'>
GREEN
2
VIP.YELLOW
VIP.GREEN
VIP.BLACk
VIP.RED

4.与普通类相比

枚举类和普通类相比,普通类的变量是可变的,并且没有防止相同标签的功能

class Common():
    YELLOW = 1

# 普通类变量,可变
Common.YELLOW = 2
print(Common.YELLOW)

结果

2

5.枚举类,注意事项

同一个枚举下,可以做is比较,以及相等比较,在不同枚举不可以比较

# 错误写法,不可以比较  
# result = VIP.GREEN > VIP.BLACk
# 正确写法,可比较
result = VIP.GREEN == VIP.BLACk
print(result)

结果

False

同一个枚举下面,变量名不可以相同,变量值可以相同,# 值相同的情况下,YELLOW_ALIAS为YELLOW的别名

class VIP(Enum):
#  注:同一个枚举下面,变量名不可以相同,变量值可以相同,
# 值相同的情况下,YELLOW_ALIAS为YELLOW的别名                     
    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACk = 3
    RED = 4
# 打印枚举中的3个变量,YELLOW_ALIAS不会被打印   
for x in VIP:
    print(x)
# 打印枚举中的4个变量,去掉items方法,只打印变量名   
for y in VIP.__members__.items():
    print(y)

# 将变量转换成枚举类
a = 3
print(VIP(a))

结果

VIP.YELLOW
VIP.BLACk
VIP.RED
('YELLOW', <VIP.YELLOW: 1>)
('YELLOW_ALIAS', <VIP.YELLOW: 1>)
('BLACk', <VIP.BLACk: 3>)
('RED', <VIP.RED: 4>)
VIP.BLACk

6.限制枚举类出现不同类型、不同值

# unique装饰器,限制变量出现相同值
@unique
# 继承IntEnum父类,限制变量出现不同类型
class VIP(IntEnum):

    YELLOW = 1
    YELLOW_ALIAS = 1
    BLACk = 3
    RED = 4

结果:执行报错,因为出现相同值

二、函数式编程

1.闭包

1.当函数环境变量,不受外部全局变量的影响,这就是闭包

def ch(x):
    def ci(y):
        c = x * y * y
        return c
    return ci
a = ch(25)
print(a(2))

# 闭包 = 函数 + 环境变量
# 当函数环境变量,不受外部全局变量的影响,这就是闭包
# 例如:环境变量 x =25,不受外部全局x=10的影响,而计算结果发生改变
x = 10
def curve_pre():
    x = 25
    def curve(y):
        c = x * y * y
        return c
    return curve
f = curve_pre()
print(f(2))
# 闭包的环境变量保存在__closure__中
print(f.__closure__)
# 打印x当前的值
print(f.__closure__[0].cell_contents)

结果

100
100
(<cell at 0x107327bb0: int object at 0x1071c43f0>,)
25

2.普通函数与闭包的区别

嵌套函数中,一个变量被认为是局部变量,而不是环境变量,那么就不算闭包,使用__closure__方法,可以查看函数是否是闭包,返回None那就不是不是闭包

def f1():
    a =10 
    def f2():
# a是一个局部变量,不是环境变量,所以不是闭包
        a =20
        return a
    return f2
f = f1()
print(f())
print(f.__closure__)

结果

20
None

注意:判断是不是闭包,可以使用__closure__方法,返回None时就不是闭包

3.事例说明闭包作用

事例:实现一个步数增加的场景,如果不使用global关键字,执行会报错。但是使用global关键字,就不是闭包了

增加global关键字,origin为全局变量

九、Python高阶语法_环境变量_02

1.闭包只会对内部环境变量发生改变,不会影响到全部变量sum

2.每调用一个函数,闭包会保存上一次执行获取的值

# 闭包只会对内部环境变量发生改变,不会影响到全部变量sum
sum = 0 
def factory(pos):
    def go(step):
# 使用nonlocal关键字,使pos成为环境变量
        nonlocal pos
        new_pos = pos + step
        pos = new_pos
        return new_pos 
    return go

s = factory(sum)
# 每调用一个函数,闭包会保存上一次执行获取的值
# 执行结果返回2,5,10
print(s(2))
print(s(3))
print(s(5))
print(sum)

结果

2
5
10
0

2.匿名函数及三元函数的使用

1.匿名函数及三元函数

匿名函数,使用lambda关键字

注:匿名函数一般在后面都是使用表达式

# 匿名函数的使用
# 注:匿名函数一般在后面都是使用表达式
a = lambda x,y : x + y
print(a(8,9))

结果

17

# 匿名函数与三元表达式结合适用于三元函数:条件为真时返回的结果 if 条件判断 else 条件为假时的返回结果

# 匿名函数与三元表达式结合适用于
# 三元函数:条件为真时返回的结果 if 条件判断 else 条件为假时的返回结果
b = lambda x,y : x if x>y else y
print(b(8,7))

结果

8

2.匿名函数与map方法的使用

打印列表中平方值

使用for循环打印和使用map方法打印

list_x = [1,2,3,4,5,6,7,9]

def square(x):
    return x * x

for x in list_x:
    print(square(x))
    
    
r = map(square,list_x)   
print(list(r))

结果

1
4
9
16
25
36
49
81
[1, 4, 9, 16, 25, 36, 49, 81]

匿名函数、map方法结合使用

使用map方法,单个参数和多个参数的使用

注:多个参数时,输出结果长度会使用最少字符串的列表传值

# map方法返回map类型
list_a = [1,2,3,4,5,6,7,9]
list_b = [3,4,5,6,7,9]

# 使用map方法,单个参数和多个参数的使用
a = map(lambda x : x*x,list_a)
print(list(a))
# 注:多个参数时,输出结果长度会使用最少字符串的列表传值
b = map(lambda x,y : x*y+x,list_a,list_b)
print(list(b))

结果

[1, 4, 9, 16, 25, 36, 49, 81]
[4, 10, 18, 28, 40, 60]

3.匿名函数与reduce方法的使用

# reduce方法返回值
a = []
for i in range(1,101):
    # 1到100追加成列表
    a.append(i)
    # 通过reduce方法,结合lambda匿名函数,完成相加
    r = reduce(lambda x,y:x+y,a)    
print(r)

b = ['ab','ac','ad','ae']
# 通过reduce方法,结合lambda完成相加,后面的10为初始化值
r = reduce(lambda x,y: x+y,b,str(10))
print(r)

结果

5050
10abacadae

4.匿名函数与filter方法的使用

# filter方法使用,抽取所有的1
list_x = [1,0,1,0,1,1,0]
r = filter(lambda x: True if x==1 else False,list_x)
print(list(r))

# filter方法使用,抽取所有的大写字母
list_y = ['a','B','c','D','E','F','g']
q = filter(lambda x : True if x.isupper() else False,list_y)
print(list(q))

# filter方法使用,抽取所有的小写字母
q = filter(lambda x : True if x.islower() else False,list_y)
print(list(q))

结果

[1, 1, 1, 1]
['B', 'D', 'E', 'F']
['a', 'c', 'g']

三、装饰器

1.装饰器的使用,简化调用时的代码

不使用装饰器,打印Hello world!

# 使用嵌套函数调用,打印“你好,世界!”
def decorator(func):
    def wrapper():
        for x in range(1,4):
            print(str(x) + '——Hello world!')
            func()
    return wrapper

def f1():
    print('你好,世界!')
# 没有使用装饰器调用函数
r = decorator(f1)
r()

结果

1——Hello world!
你好,世界!
2——Hello world!
你好,世界!
3——Hello world!
你好,世界!

使用装饰器打印Hello world!

def decorator(func):
    def wrapper():
        for x in range(1,4):
            print(str(x) + '——Hello world!')
            func()
    return wrapper
 
 # 通过装饰器先调用decorator
@decorator
def f2():
    print('你好,wode世界!'*3)
# 使用装饰器调用
f2()

结果

1——Hello world!
你好,wode世界!你好,wode世界!你好,wode世界!
2——Hello world!
你好,wode世界!你好,wode世界!你好,wode世界!
3——Hello world!
你好,wode世界!你好,wode世界!你好,wode世界!

2.可变参数的情况下使用装饰器

import time

def Log_structure (func): 
    # *args可变参数
    def log_time(*args):
        print(time.time())
        func(*args)
    return log_time
    
@Log_structure   
def Log_content01(log01,log02):
    print('This is log 01:'+ log01)
    print('This is log 02:'+ log02)
    
Log_content01('error','success')

结果

1656075871.8154051
This is log 01:error
This is log 02:success

3.可变参数+关键字参数情况下使用装饰器

*args可变参数+**kw关键字参数情况下使用装饰器

def Log_structure (func): 
    # *args可变参数+**kw关键字参数
    def log_time(*args,**kw):
        print(time.time())
        func(*args,**kw)
    return log_time
    
@Log_structure   
def Log_content01(log01,log02,**log03):
    print('This is log 01:'+ log01)
    print('This is log 02:'+ log02)
    print(log03)
    
    
Log_content01('error','success',Log_content = 'uncertain',long_content1 = 'uncertain1')

结果

1656075871.815507
This is log 01:error
This is log 02:success
{'Log_content': 'uncertain', 'long_content1': 'uncertain1'}

4.注意事项

1、使用可变参数和关键字参数,参数命名可根据具体需求变更

2、使用可变参数和关键字参数,调用时,可以随意使用任何参数

3、装饰器不仅可以简化代码,还可以是一个控制器

### Python 高级语法特性和使用示例 #### 类装饰器与元类 Python 提供了强大的面向对象编程支持,其中类装饰器和元类是两个重要的概念。通过这些工具可以实现更灵活的对象行为控制。 类装饰器是一种用于修改或增强类功能的方法。下面是一个简单的例子: ```python def decorator(cls): class NewClass(cls): def new_method(self): print("This is a new method.") return NewClass @decorator class MyClass: pass obj = MyClass() obj.new_method() # 输出 "This is a new method." ``` 元类允许程序员定义类的行为方式,在创建新类时自动应用某些规则[^1]。 #### 异步编程 异步编程模型使得程序可以在等待 I/O 操作完成时不阻塞主线程。`asyncio` 库提供了完整的基础设施来构建高效的并发应用程序。 这里有一个基本的例子展示如何编写异步函数并运行它们: ```python import asyncio async def say_after(delay, what): await asyncio.sleep(delay) print(what) async def main(): task1 = asyncio.create_task(say_after(1, 'hello')) task2 = asyncio.create_task(say_after(2, 'world')) await task1 await task2 await main() ``` #### 动态属性访问 动态属性访问是指在不预先声明的情况下获取或设置实例变量的能力。这可以通过 `__getattr__()`, `__setattr__()`, 和其他特殊方法来实现。 例如,我们可以创建一个能够处理未知属性请求的对象: ```python class DynamicAttributes: def __init__(self): self._attributes = {} def __getattr__(self, name): try: return self._attributes[name] except KeyError as e: raise AttributeError(f"'{type(self).__name__}' object has no attribute '{e.args[0]}'") def __setattr__(self, key, value): if key.startswith('_'): super().__setattr__(key, value) else: self._attributes[key] = value dyn_obj = DynamicAttributes() dyn_obj.x = 42 print(dyn_obj.x) # 输出 42 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值