筱团Blog筱团のBlog

python 中级用法

筱团·2022-07-26 16:35·124 次阅读

python 中级用法

Prerequisite#

老是用那几个 crud,都忘了类啊,装饰器啥的怎么用,重新回来学学~
参考文章:廖雪峰

基础知识

*args 是非关键字参数,用于元组,**kw 是关键字参数,用于字典
同时使用 *args 和 **kwargs 时,必须 *args 参数列要在 **kwargs 前(比如 foo(a=1, b='2', c=3, a', 1, None, ) 会报错)

Copy
def foo(*args, **kwargs): print('args = ', args) print('kwargs = ', kwargs) print('---------------------------------------') if __name__ == '__main__': foo(1, 2, 3, 4) foo(a=1, b=2, c=3) foo(1, 2, 3, 4, a=1, b=2, c=3) foo('a', 1, None, a=1, b='2', c=3) ''' args = (1, 2, 3, 4) kwargs = {} --------------------------------------- args = () kwargs = {'a': 1, 'b': 2, 'c': 3} --------------------------------------- args = (1, 2, 3, 4) kwargs = {'a': 1, 'b': 2, 'c': 3} --------------------------------------- args = ('a', 1, None) kwargs = {'a': 1, 'b': '2', 'c': 3} --------------------------------------- '''

关键字参数

Copy
import os import argparse if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--theme', default='校园爱情', type=str, help='主题') parser.add_argument('--file', default='./input/', type=str, help='文件地址') args = parser.parse_args() if not os.path.exists(args.file): print('Cannot find input path: {0}'.format(args.file)) exit() print(args.theme, args.file) ''' python test.py --theme "happy" --file "./input/" --------------------------------------- happy ./input/ '''

sys
这种方法可以引用上层文件

Copy
import sys sys.path.append("..") # 或者 sys.path.append(os.path.join(os.path.dirname(__file__), ".."))

subprocess

Copy
import subprocess def runcmd(command): # 不显示输入内容 stdout=subprocess.PIPE, stderr=subprocess.PIPE # 编码方式 encoding="utf-8" ret = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if ret.returncode == 0: return("success:", ret) else: return("error:", ret) runcmd(["python", "--version"])

super()._init_()
针对子类的,用于自动初始化,减少代码数的语句
参考博客:理解super()._init_()

Copy
class Car(object): def __init__(self, owner, year, model): self.owner = owner self.year = year self.model = model class ElectricalCar(Car): def __init__(self, battery, *args, **kwargs): # 将剩下的参数打包送给 super super().__init__(*args, **kwargs) # 从参数列表中拿出 battery 初始化子类属性 self.battery = battery def get_power(self): """打印电池信息""" print(f'The battery of this car is {self.battery}') car = ElectricalCar('10000kwh','Jarry', 2021, 'Model S') car.get_power() print(car.owner, car.year, car.model) """ The battery of this car is 10000kwh Jarry 2021 Model S """

判断 变量/函数 类型

Copy
# 一般用 type 就行了 type(123) # <class 'int'> type(abs) # <class 'builtin_function_or_method'> type(a) # <class '__main__.Animal'> type(fn)==types.FunctionType # True type(abs)==types.BuiltinFunctionType # True type(lambda x: x)==types.LambdaType # True type((x for x in range(10)))==types.GeneratorType # True # 类就用 isinstance # 实际上 type 能用的 isinstance 都能用,建议优先使用 isinstance 判断类型 # object -> Animal -> Dog -> Husky isinstance(h, Dog) # True

执行字符串

Copy
expr = """ a, b = ["123", "456"] print(a, b) """ exec(expr) # 123 456

直接赋值、浅拷贝和深度拷贝
列表和元组的浅拷贝(copy),可以分出两个独立的对象
字典的赋值和浅拷贝(copy)没区别,只有深拷贝可以分出两个独立的对象

Copy
# 赋值,相当于别名 # 字典浅拷贝 a = {1: [1,2,3]} b = a.copy() print(a, b) # ({1: [1, 2, 3]}, {1: [1, 2, 3]}) a[1].append(4) print(a, b) # ({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]}) # 字典深拷贝 import copy c = copy.deepcopy(a) print(a, c) # ({1: [1, 2, 3, 4]}, {1: [1, 2, 3, 4]}) a[1].append(5) print(a, c) # ({1: [1, 2, 3, 4, 5]}, {1: [1, 2, 3, 4]})

创建二维数组

Copy
# 1. 直接创建法 test = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] # 2. 列表生成式法 test = [[0 for i in range(m)] for j in range(n)] # 3. numpy 创建 import numpy as np test = np.zeros((m, n), dtype=np.int)

高级特性

生成器 generator#

简单介绍

Copy
# 普通列表 L = [x * x for x in range(10)] print(L) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # 生成器 g = (x * x for x in range(10)) print(next(g)) # 0 print(next(g)) # 1 print(next(g)) # 4 for n in g: print(n) ''' 9 16 25 36 49 64 81 '''

斐波那契的运用

Copy
# 最普通的斐波那契 def fib(max): n, a, b = 0, 0, 1 while n < max: print(b) a, b = b, a + b n = n + 1 return 'done' # 使用了生成器的斐波那契(print 变成了 yield) def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done' # 正常的输出,最后不会输出 done for n in fib(6): print(n) # 最后会输出 done g = fib(6) while True: try: x = next(g) print('g:', x) except StopIteration as e: print('Generator return value:', e.value) break

迭代器#

可迭代对象:Iterable
迭代器:Iterator

凡是可作用于 for 循环的对象都是 Iterable 类型
凡是可作用于 next() 函数的对象都是 Iterator 类型,它们表示一个惰性计算的序列

Copy
# 集合数据类型如 list、dict、str 等是 Iterable 但不是 Iterator,不过可以通过 iter() 函数获得一个 Iterator 对象 # Python 的 for 循环本质上就是通过不断调用 next() 函数实现的,例如: for x in [1, 2, 3, 4, 5]: pass # 完全等价于 # 首先获得Iterator对象: it = iter([1, 2, 3, 4, 5]) # 循环: while True: try: # 获得下一个值: x = next(it) except StopIteration: # 遇到StopIteration就退出循环 break

函数式编程

匿名函数 lambda#

直接举例

Copy
def is_odd(n): return n % 2 == 1 L = list(filter(is_odd, range(1, 20))) # 完全等价于 L = list(filter(lambda n:n%2 == 1 , range(1,20)))

装饰器#

一句话,装饰器就是给原函数添加额外的功能(迭代原函数)的东西
装饰器的英文是 decorator,装饰器分为传参和非传参,下面写了两个模板

Copy
from datetime import datetime import functools # 一个普通的函数 def now(): print(datetime.now()) # 运行函数和打印函数的名字 now() # 2022-07-26 17:55:02.891440 print(now.__name__) # now # 普通的装饰器(两层) # @functools.wraps(func) 的功能相当于 wrapper.__name__ = func.__name__ # 使用 *args, **kw 的目的是完全接收 func 原本的传参 def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper @decorator def now(): print(datetime.now()) now() # call now(): # 2022-07-26 17:58:56.143251 print(now.__name__) # now # 使用参数的装饰器(三层) def log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print('%s %s():' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator @log('text') def now(): print(datetime.now()) now() # text now(): # 2022-07-26 17:59:50.026713 print(now.__name__) # now

偏函数#

偏函数可以简化参数操作
当函数的某个参数是我们可以提前获知的,那我们就可以将它固定住!

Copy
import functools # 定义一个取余函数,默认和2取余; def mod(x,y=2): # 返回 True 或 False return x % y == 0 # 假设我们要计算和3取余,如果不使用partial()函数,那么我们每次调用mod()函数时,都要写y=3 mod(4,y=3) mod(6,y=3) # 使用partial()函数 mod_3 = functools.partial(mod,y=3) mod_3(4) mod_3(6)
posted @   筱团  阅读(124)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
点击右上角即可分享
微信分享提示
目录