pythonic

1.  c1.py


# 通过字典映射的关系,来模拟switch功能
# 不建议使用下标的方式,强烈推荐使用get方法
# 推荐使用函数式编程,字典的键值也可以为一个函数,推荐使用
    # 当使用函数方式,需要让函数执行,调用方法后应该加一个括号;
    # 此时使用的默认值也不能直接使用字符串了,字符串后加括号会报错,
    # 思路一 (通过判断返回值的类型,执行对应方式方法)
        # 将执行get的返回用一个变量接住,判断这个变量的类型,
        # 数据类型如果是字符串直接返回,如果为函数则执行该方法,也可以起到容错作用,但这样比较麻烦,最好在定义时统一最好
    # 思路二 (统一默认值和返回值都是函数形式)  (推荐)
        # 将返回默认值也改为函数形式,这时返回的结果都是方法了,都能执行
    

# 例如:模拟星期对应

# 普通方式
switcher = {
    0 : 'Sunday',
    1 : 'Monday',
    2 : 'Tuesday',
    3 : 'Wednesday',
    4 : 'Thursday',
    5 : 'Friday',
    6 : 'Saturday'
}
day = 7
# print(switcher[day])
# 这种通过下标访问的方式会存在一些问题,当下标不存在时会报错
# 比较建议使用get方法
# get需要传递两个参数:第一个day参数,第二个默认值(在找不到时,会返回默认值)
print(switcher.get(day,'None'))

# 函数方式
def sunday():
    return 'Sunday'
def monday():
    return 'Monday'
def tuesday():
    return 'Tuesday'
switcher1 = {
    0 : sunday,
    1 : monday,
    2 : tuesday
}

day1 = 2
print(switcher1.get(day1,'None')())

# 在定义时统一默认值和返回值的类型 (此法甚好)
def sunday2():
    return 'Sunday'
def monday2():
    return 'Monday'
def tuesday2():
    return 'Tuesday'

def default_value():
    return 'None'
switcher2 = {
    0 : sunday2,
    1 : monday2,
    2 : tuesday2
}

day2 = 2
print(switcher2.get(day2,default_value)())

2.  c2.py


# 列表推导式
    # 适用起来还是很方便的 (在其它的语言中map比较多,可能有些人使用map会比较熟悉)   
    # 但在有些情况,使用列表推导式会特别好,例如:对大于5的做平方,小于5的不用管
    # 对于set数据类型,也可使用列表推导式,如果列表推导式用的'[]'返回结果是list(列表)类型;如果列表推导式用的'{}'返回结果是set(集合)类型;

# 求一组数的平方

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

# 如果不适用列表推导式,可以有两种方法:1.for循环;2.map
    # 1.for循环
    # for i in a:
    #     print(i*i)
# 2.map函数
    # (1)有名函数
    # def sqr(i):
    #     return i*i
    # b1 = map(sqr,a)
    # print(b1) #<map object at 0x00000000021BF470>
    # print(list(b1)) #[1, 4, 9, 16, 25, 36, 49, 64]
    # (2)匿名函数
    # b2 = map(lambda x:x*x, a)
    # print(b2) #<map object at 0x00000000026DF438>
    # print(list(b2)) #[1, 4, 9, 16, 25, 36, 49, 64]

# 3.列表推导式
    # (1)平方的方式一
    # b3 = [i*i for i in a]
    # print(b3)
    # (2)平方的方式二
    # b4 = [i**2 for i in a]
    # print(b4)

# 4.对大于5的做平方,小于5的不用管
    # b4 = [i*i for i in a if i>=5]
    # print(b4) #[25, 36, 49, 64]
# 5.如果数据是set也可
a1 = {1,2,3,4,5,6,7,8}
b5 = [i**2 for i in a1 if i>=5]  #外边包裹[],导致返回结果数据类型不一样
print(b5) #[25, 36, 49, 64]
b6 = {i**2 for i in a1 if i>=5}  #外表包裹{},导致返回结果数据类型不一样
print(b6) #{64, 25, 36, 49}


3.  c3.py


# 对于字典的列表推导式的写法

students = {
    '石敢当' : 13,
    '喜小乐' : 11,
    '王小五' : 15
}

# 1.将所有的key提取出来
    # 注意点:students是一个dic(字典),直接拿key和value是拿不到的,须要使用dic的items方法
    # (1)直接拿不到,会报错
    # a1 = [key for key,value in students]
    # print(a1)
    # (2)使用items方法
    # a2 = [key for key,value in students.items()]
    # print(a2) #['石敢当', '喜小乐', '王小五']
# 2.将key和value进行替换顺序 (此时是字典类型,推导式外层也须写为'{}'而非'[]')
    # a3 = {value:key for key,value in students.items()}
    # print(a3) #{13: '石敢当', 11: '喜小乐', 15: '王小五'}

# 3.元组,也可以使用处理一些数据,但不推荐使用
    # a4 = (key for key,value in students.items())
    # print(a4) # <generator object <genexpr> at 0x0000000001E11570> 返回的是一个generator对象
    # 对这个generator对象进行遍历
    # for i in a4:
    #     print(i)

4.  c4.py


# 列表、元组、集合

# 可迭代对象、迭代器
    # 可迭代的对象不一定是迭代器 (例如:列表、元组 就不是迭代器)
    # 迭代器 一定是 可迭代对象

# 可迭代对象(iterable):能被for in遍历的对象都是可迭代对象 (例如:列表、元组、集合)
    # 不可以 使用next函数进行遍历
    # 列表和元组,不论循环几次都会打印几次
# 迭代器(iterator):首先是一个对象 class 自己定义的一个普通的class不能被for in遍历,但变成迭代器后就可了
    # 可以   使用next函数进行遍历
    # 迭代器 只能使用  一次 for in遍历,第二次就不执行了 (例如:执行两次for循环打印,值执行一次)
    # 如果想多次打印:方案一:多次实例化,分别打印;方案二:进行拷贝(拷贝分深拷贝deepcopy和浅拷贝copy),打印拷贝的

# 普通对象可以变为迭代器
    # 增加两个函数(__iter__,__next__),只要增加了这两个函数,就变成了迭代器
    # 当每次调用for in 循环的时候都会调用一次__next__函数,所以须在__next__函数返回一个数据,当调用结束没有数据返回,就得在__next__中抛出一个异常

class BookCollection:
    def __init__(self):
        self.data = ['《往事》','《只能》','《回味》']
        self.cur = 0

    def __iter__(self):
        # 需要返回自身
        return self

    def __next__(self):
        # 当遍历完成,需要抛出一个异常 ( raise StopIteration() )
        if self.cur >= len(self.data):
            raise StopIteration()
        r = self.data[self.cur]
        self.cur += 1
        return r

books = BookCollection()
# 方式一:通过for in 来遍历
    # for i in books:
    #     print(i)
    # 可以试一下,只打印一次哦
    # for i in books:
    #     print(i)
# 方式二:通过next函数 (next只能对迭代器使用,不能对列表使用)
    # print(next(books))
    # print(next(books))
    # print(next(books))

# 多次打印
    # books1 = BookCollection() 
    # books2 = BookCollection()
    # for i in books1:
    #     print(i)
    # for i in books2:
    #     print(i)

# 深浅拷贝
    # 先引入 copy
import copy
books3 = BookCollection()
    # (1)浅拷贝
    # books4 = copy.copy(books3)
    # for i in books3:
    #     print(i)
    # for i in books4:
    #     print(i)
    # (2)深拷贝
    # books5 = copy.deepcopy(books3)
    # for i in books5:
    #     print(i)

5.  c5.py


# 生成器

# print 0-10000

# 方案一:列表推导式
    # 有缺点:非常消耗计算机的资源(内存)

# n是一个列表,消耗内存
n = [i for i in range(0,10001)]
# print(n)
# for i in n:
#     print(i)

# 这里用生成器(generator)
    # 只是一个算法,不会过度占用资源
    # 虽然不会导致性能问题,但内部直接打印,没有什么意义 (一般会拿到值,在外部做一些操作)
    # 此时,会想着直接return,但如果用了return,语法检测会报错;要将return改为yield关键字
    # 生成器(generator)可以使用next方法调用,或者使用for循环
    # 生成器的优势:既保证了函数的通用性,也保证了性能问题
    # 生成器的内部没有保存数据,保存的是一个算法
    # 列表推导式外层的'[]'改为'()'那就变为生成器

# def max1(x):
#     y1 = 0
#     while y1 <= x:
#         print(y1)
#         y1 += 1
# max1(10000)

# 返回一个值
def max2(x):
    y2 = 0
    while y2 <= x:
        y2 += 1
        # return 会报语法错误
        # return y2
        yield y2
# 此时得到的是一个 generator 对象 (generator:就是一个生成器)
# print(max2(10000)) #<generator object max2 at 0x0000000002161570>
    # (1)next方法调用
        # g = max2(10000)
        # print(next(g))
        # print(next(g))
    # (2)for循环调用
        # for i in max2(10000):
        #     print(i)

# 列表推导式外层的[]和()不同
    # n1 = [i for i in range(0,10001)]  #list形式,消耗内存资源
    # n2 = (i for i in range(0,10001))  #<generator object <genexpr> at 0x0000000002141570>  generator:生成器
    # print(n1)
    # print(n2)

# yield 关键字
    # return 会返回,函数中执行return时,return后边的语句都不执行
    # yield  会保存上次的结果,当执行next后继续执行时,不会终止后续的执行

6.  c6.py


# None
    # python中的'None'和其它的语言中的none不同
    # None 不会代表    空字符串、空列表、0、False 
    # 空字符串、空列表、0、False 的 类型、取值和None都不同

# 判空时,结果有不同 (最后边的例子)
    # 当a1为None时返回结果相同
    # 但当a1为空时,返回就不同了
    # 所以在判断是否为空时,强烈推荐使用: (1)if not a  (2)if a  这两种方式比较稳妥哦! (当a='',a=[],a=False时都能得到想要的结果)

# None 和False
    # 数据类型: None : NoneType类型; False:(布尔)bool类型
    # 表示意义: None : 不存在; False:真假

# print(type(False))

a = ''
b = []
c = False

# print(a == None)  #false
# print(b == None)  #false
# print(c == None)  #false

# print(a is None)  #false

# print(type(None)) #<class 'NoneType'>  None 的类型就直接为NoneType类型


# 判空时,结果有不同
def none_fun():
    return None

# 这种写法,语法规范通不过,但能运行
    # 当a1为None时返回结果相同
    # 但当a1为空时,返回就不同了
# a1 = none_fun()
# a1 = []

# if not a1:
#     print('S')
# else:
#     print('F')

# if a1 is None:
#     print('S')
# else:
#     print('F')

7.  c7.py


# (if a:) 和 (if None:) 走的分支一样,在Python中其它数据类型和bool存在一个对应的关系
# 对于自定义的类,如果内部没有嵌套方法和嵌套方法,返回的结果不同
    # 如果类下边既没有定义 '__len__' 也没有定义 '__bool__' ,则返回真
    # 类的返回真假和内部的两个函数相关  __len__,__bool__
    # 当类的__bool__这个方法不存在时,类的返回结果由__len__决定;当两个都存在时,只受__bool__影响

# a = ''
# b = []
# c = False

# print(a == None)  #false
# print(b == None)  #false
# print(c == None)  #false

class Test():
    # 嵌套这个内置方法和不嵌套这个内置方法,返回结果不同哦
    def __len__(self):
        # 这里的返回只能是 正整数、0、bool(False,True)
            # 0:整个类的返回结果为 False
            # 其它正整数:整个类的返回结果为 True
            # bool:True为True,False为False
            # 字符串之类的,则非法了,这里本来就是len指长度,怎么能为str呢?
        return 0
    def __bool__(self):
        # 这里的return只能是 bool(False,True),其它类型的数据都会报错
        return False
    pass

test = Test()
# 这里系统的len方法,会调用定义类里的__len__方法,如果对象中没有定义__len__方法,会报len方法不存在
print(len(test))
print(bool(test))

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

8.  c8.py

import time
from functools import wraps

# 函数添加装饰器,对函数本身产生的影响
    # 不加装饰器,函数的name是函数的名;加了装饰器,函数name就改变了
    # 不加装饰器,(通过help可以查看 print(help(f)) )函数名,注释都能获取;使用了装饰器,函数名改变了,当前函数的注释说明等也不能获取了,装饰器不能滥用
    # 函数名改变不可取,Python中又提供了一个wraps装饰器,通过该装饰器可以保证名字不改变 
    # 引入wraps装饰器,在闭包函数上方使用装饰器即可,wraps装饰器可以接收参数,将原函数名当做装饰器的参数传入,就能实现使用了装饰器,原函数名不变

# 使用了装饰器wraps之后,原函数的信息没有被改变le
    # 加装饰器,使用了闭包函数,相当于执行的是内部的wrapper函数,函数名等等信息就变成了内部wrapper函数的信息
    # 通过装饰器函数 wraps 将原函数当做参数传入wraps中,从而实现了信息的替换,所以信息就没被改变了

def decorator(func):
    @wraps(func)
    def wrapper():
        print(time.time())
        func()
    return wrapper

@decorator
def f():
    '''
        this is f funciton introduce
    '''
    print(f.__name__)
# f() 
print(help(f))

(备注:以上内容来自七月老师的学习笔记,仅作为学习使用)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值