Python入门学习(十)第十四章其他

一、用字典映射代替switch语句

'''
用字典来代替其他语言中的switch实现
day = 2
switch(day)
{
    case 0:
        daytime="Sunday";
        break;
    case 1:
        daytime="Monday";
        break;
    case 2...

    default:
        dayname = "Unknown";
        break;
}

'''
day = 5
daytime_switchers = {
    0 : "Sunday",
    1 : "Monday",
    2 : "Tuesday"
}
#day_name = daytime_switchers[day]

#但switch语句中一般还有default分支默认值的情况
#可以通过字典的get方法
#get方法第一个参数对应键,如键不存在时则返回第二个参数内容
day_name = daytime_switchers.get(day, "Unknown")
print(day_name)

如果switch分支对应的是代码块,则在字典键内容中设置函数去实现

'''
用字典来代替其他语言中的switch实现
如果switch分支中对应的是代码块
则可以通过字典值中设置不同的函数去实现
'''
day = 2
def get_sunday():
    return "Sunday"

def get_monday():
    return "Monday"

def get_tuesday():
    return "Tuesday"

def get_default():
    return "Unkonw"

daytime_switchers = {
    0 : get_sunday(),
    1 : get_monday(),
    2 : get_tuesday()
}

day_time =daytime_switchers.get(day, get_default())
print(day_time)

 

二、列表推导式

#列表推导式

a = [1, 2, 3, 4, 5, 6, 7, 8]

#从上述已知列表a获取新列表,元素为对应的平方
#第一种方法是通过map映射
b = map(lambda x : x*x, a)
print(list(b))
#第二种通过原始的实现
b = []
for i in a:
    b.append(i * i)
print(b)
#第三种就是列表推导式
b = [i * i for i in a]
print(b)
a = [1, 2, 3, 4, 5, 6, 7, 8]

#如果要对列表a中大于等于5的元素作立方运算,并用列表输出
#map则不是太合适,需要先对原列表分解出对应条件的集合再去映射
#或者配合filter实现
c = filter(lambda x:1 if x >= 5 else 0, a)
b = map(lambda i : i**3, list(c))
print(list(b))
#用for自然也可以实现
#但用列表推导式是最简便快速的
b = [i**3 for i in a if i >= 5]
print(b)

从上面代码可看出:列表推导式分为三部分:1、运算规则;2、遍历;3、遍历元素筛选条件

列表推导式对序列也是通用的,如果想得到集合则推导式需要使用{},如想到元组则使用():

 

#列表推导式对序列也是通用的
a = [1, 3, 5, 5, 7, 9]
t1 = (i**2 for i in a)
s1 = {i**2 for i in a}
print(tuple(t1))
print(set(s1))

 

#字典的推导式

students = {
    "王斌" : 28,
    "李晓明" : 36,
    "Mike" : 26
}

#尝试把key提取出来作为一个元组
b = [key for key,value in students.items()]
print(b)

#如果要把键-值做一个颠倒
b = {value : key for key,value in students.items()}
print(b)

#如果把键值对做成元组
b = ({key:value} for key,value in students.items())
print(tuple(b))
#或者:
b_key = (key for key,value in students.items())
print(tuple(b_key))
b_value = (value for key,value in students.items())
print(tuple(b_value))

#如果把键值对做成列表
b = [{key:value} for key,value in students.items()]
print(b)

三、关于组、序列的概念:iterator和generator

1、可迭代对象:是指可以被遍历的对象,如列表、元组、集合、字典,也包括一些具备迭代器(iterator)功能的对象

#创建一个可遍历的类
#类必须被设计为具备迭代器功能的才可以被for/in迭代
#必须具有__iter__()和__next__()两个方法
class BookCollection:
    def __init__(self):
        self.data = ["边城", "三体", "平凡的世界", "金锁记"]
        self.cur = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.cur >= len(self.data):
            raise  StopIteration
        r = self.data[self.cur]
        self.cur += 1
        return r


books = BookCollection()
for book in books:
    print(book)

for book in books:
    print(book)

2、生成器

#生成器
#如果要生成1~10000的数字
#可以用列表推导式
#n = [i for i in range(1, 10001)]
#print(n)
#上述代码虽然可以实现功能,但非常消耗计算机内存
#有没有什么方法可以不过多消耗计算机内存,又能实现这一功能
#如下可以:
'''
def gen(max):
    n = 0
    while n <= max:
        print(n)
        n += 1

gen(10005)
'''
#但上述gen()函数不只是提供了数字,还兼顾实现了打印功能
#这种方式把数据获取和业务功能捆绑在一起,并不合理
#有没有单纯的可以获取数据呢
def gen(max):
    n = 0
    while n <= max:
        n += 1
        yield n      #通过yield则gen()就变成了一个生成器
        #yield与return不同,return会直接退出函数,yield则会继续循环

g = gen(20)
print(next(g))
print(next(g))
print(next(g))
print(("........................."))
#可以如上逐次通过next()调用获取
#也可以通过for in遍历生成器
for i in g:
    print(i)

四、关于None

None即表示“空”,而非(不等于)0、空字符串、空列表、false等

a = ""
b = False
c = 0
d = []

print (a == None)
print (b == None)
print (c == None)
print (d == None)
#以上均打印“False”

python中的“None”本身也是一个对象

print(type(None))
#打印“<class 'NoneType'>”

可以看出None属于Nonetype类型,而False是布尔类型。

a = []

if not a:
    print("S")
else:
    print("F")
#以上输出"S"

if a is None:
    print("S")
else:
    print("F")
#以上输出"F"
#说明空列表的反义(not a)为真,但空列表a却不等同于None
print(type(a))
#可以看出a仍为列表类型,但前面我们得知None是“NoneType”类型

 对象存在并一定是True

class Test():
    def __len__(self):
        return 10
    #类中的__len__方法返回为0,则该类创建的对象对应布尔值为False,非0则为True
    def __bool__(self):
        return False
    #类中__bool__方法也可以设置实例对象对应布尔值为真或伪
    #同时,__bool__方法设置的优先级是大于__len__方法的

test = Test()

print(bool(None))   #False
print(bool([]))  #False
print(bool(test))  #False

if test:
    print("S")
else:
    print("F")

五、关于装饰器的“副作用”

import time

def showtime_deco(func):
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        print("The Function runed for", str(t2-t1), "seconds.")
    return wrapper

@showtime_deco
def f1():
    '''
        This is f1 function.
    :return: None
    '''
    print("This is the f1 function.")
    print(f1.__name__)


print(help(f1))
f1()
#可以发现打印函数名称输出的是wrapper,而非原函数名f1

可以通过给f1()保留和去掉装饰器之后运行的差异发现:1、函数名发生变化,加上装饰器之后函数名打印为wrapper;2、原函数f1的注释文档在help(f1)中未显示,只显示wrapper()

这些就是装饰器对原函数的副作用

要保持原函数名不变并且help可以显示原函数的注释文档,可以导入wraps,并且将其作为既有装饰器内部函数的装饰器:

import time
from functools import  wraps
def showtime_deco(func):
    @wraps(func)
    def wrapper():
        t1 = time.time()
        func()
        t2 = time.time()
        print("The Function runed for", str(t2-t1), "seconds.")
    return wrapper

@showtime_deco
def f1():
    '''
        This is f1 function.
    :return: None
    '''
    print("This is the f1 function.")
    print(f1.__name__)


print(help(f1))
f1()
#可以发现打印函数名称输出的是wrapper,而非原函数名f1

六、python3.8新增的海象运算符

#walrus operator 海象运算符 :=

a = "python3.8"

b = len(a)

if b > 5:
    print("长度大于5;"+ "实际长度为"+str(b))

print("-------------以上为传统的写法-------------")
print("-------------下面为海象运算符写法--------------")

if (c:=len(a)) < 10:    #需要注意海象运算符优先级较低,需要括号
    print("长度小于10," + "实际长度为" + str(c))

七、字符串拼接

a = 3
b = 5
print(str(a),"",str(b),"之和为",str(a+b))
print(str(a)+""+str(b)+"之和为"+str(a+b))

#用f+{}形式拼接更为方便
print(f"{a}和{b}之和为{a+b}。")

八、python3.7新增数据类dataclass装饰器

原来的写法:

class Student():
    def __init__(self, name, age, school_name):
        self.name = name
        self.age = age
        self.school = school_name

    def test(self):
        print(self.name)

student = Student("Michale", 18, "Tsinghua")

student.test()

使用dataclass装饰器的写法:

from dataclasses import dataclass

@dataclass
class Student():
    name : str
    age : int
    school_name : str
    #上述代码等同于__init__构造函数

    def test(self):
        print(self.name)

student = Student("Michale", 18, "Tsinghua")
print(student.__repr__())
student.test()

 

posted @ 2025-08-25 12:54  tsembrace  阅读(8)  评论(0)    收藏  举报