# learnPython **Repository Path**: ssfanli/learnPython ## Basic Information - **Project Name**: learnPython - **Description**: Python每日学,贵在坚持! - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2019-05-11 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## learnPython Python每日学,贵在坚持! ### 介绍 [廖雪峰Python教程学习笔记](https://www.liaoxuefeng.com/wiki/1016959663602400) [学习景霄Python核心技术学习笔记](https://time.geekbang.org/column/intro/176) ### 版本 Python3+ ### 一、廖雪峰Python #### 01 | 查找文件名并返回绝对路径 编写一个程序,能在当前目录以及当前目录的所有子目录下查找文件名包含指定字符串的文件,并打印出相对路径 ``` #!/usr/bin/env python3 # -*-coding: utf-8-*- # The function of find target string and return abs path import os import sys sys.path.append('.') def find_target(path, target): for i in os.listdir(path): d_path = os.path.join(path, i) # os.path.isdir/isfile('需要输入路径/文件路径'),返回`True` or `False` if os.path.isdir(d_path): find_target(d_path, target) # 递归 else: if target in os.path.splitext(i)[0]: # `os.path.splitext(i)`返回一个元组,拆分开文件名和文件后缀 print(os.path.abspath(d_path)) # 不能用`return`,否则直接返回 if __name__ == '__main__': path = sys.argv[-2] tar = sys.argv[-1] find_target(path, tar) ``` #### 02 | 合并多个字典 合并多个字典,参考[Python优雅的合并两个Dict](https://segmentfault.com/a/1190000010567015) ```angular2html #!/usr/bin/env python3 # -*- coding:utf-8 -*- # module of merge two dict d1 = {'a': 1, 'b': 2} d2 = {'c': 3, 4: 'ss'} # Method 1, python3.5+ needed d3 = {**d1, **d2} print('d3=', d3) # Method 2,merge 2 dict def merge_dict(x, y): z = x.copy() z.update(y) return z # Method 3, merge several dict def merge_several_dict(*d): new_d = dict() for i in d: new_d.update(i) return new_d # Method 4, 序列自增方法 d4 = {k: v for d in (d1, d2) for k, v in d.items()} print(d4) if __name__ == '__main__': print(merge_several_dict(d1, d2, {'ss': 22})) print(merge_dict(d1, d2)) ``` #### 03 | Python序列化 1. pickle.dumps(d),序列化python对象d 2. pickle.dump(d, f),把python对象d序列化并写到f文件 3. pickle.load(f),把f文件的序列化数据转化(反序列化)为python对象 4. pickle.loads(d),把d反序列化为python对象 ``` #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ @Author: Lidi @Time : 20190514 @Desc : python 序列化模块pickle """ import pickle # pickle.dumps()方法把任意对象序列化成一个bytes d = dict(name = 'lidi', age = 27) du = pickle.dumps(d) print(du) # pickle.dump(dict, file),把任意对象序列化后写入文件 f = open('dump.txt', 'wb') pickle.dump(d, f) f.close() # 当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象,也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象。我们打开另一个Python命令行来反序列化刚才保存的对象 f = open('dump.txt', 'rb') d = pickle.load(f) f.close() print(d) ``` #### 04 | 子进程`subprocess`模块 1. subprocess.call() ``` call(*popenargs, timeout=None, **kwargs) Run command with arguments. Wait for command to complete or timeout, then return the returncode attribute. The arguments are the same as for the Popen constructor. Example: retcode = call(["ls", "-l"]) >>> subprocess.call(['dir', '-l']) ``` 2. subprocess.Popen() ``` >>> s = subprocess.Popen('ping www.baisu.com', stdin=subprocess.PIPE, stdout=subprocess .PIPE, stderr=subprocess.PIPE, shell=True) >>> out, err = s.communicate() # 返回类型为tuple,获得子进程输出和错误输出 >>> out.decode('gbk') # 返回类型需要解码 ``` #### 05 | 多线程 > Python的标准库提供了两个模块:_thread和threading,_thread是低级模块,threading是高级模块,对_thread进行了封装。绝大多数情况下,我们只需要使用threading这个高级模块。 启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行 ``` #!/usr/bin/env python3 # -*- coding: utf-8 -*- # learn threading import threading import time def loop(): print('thread %s is running...' % threading.current_thread().name) n = 0 while n < 5: n += 1 print('thread %s >> %s' % (threading.current_thread().name, n)) time.sleep(1) print('thread %s is ended.' % threading.current_thread().name) print('thread %s is running...' % threading.current_thread().name) t = threading.Thread(target=loop, name='LoopThread') t.start() # 启动线程 t.join() # 等待线程结束 print('thread %s ended.' % threading.current_thread().name) ``` > threading.current_thread(): 返回当前线程的实例 threading.currentThread(): 返回当前的线程变量。 threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。 threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。 除了使用方法外,线程模块同样提供了Thread类来处理线程,Thread类提供了以下方法: run(): 用以表示线程活动的方法。 start():启动线程活动。 join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。 isAlive(): 返回线程是否活动的。 getName(): 返回线程名。 setName(): 设置线程名。 --- ### 二、景霄Python #### 01 | replace/re.sub()/re.split() **1. replace** ```angular2html >>> help(str.replace) Help on method_descriptor: replace(...) S.replace(old, new[, count]) -> str Return a copy of S with all occurrences of substring old replaced by new. If the optional argument count is given, only the first count occurrences are replaced. # count - 替换次数 >>> s = '123-456-789-10111213' >>> s '123-456-789-10111213' >>> s.replace('-', '*', 2) '123*456*789-10111213' ``` **2. re.sub()正则替换** ```python Help on function sub in module re: sub(pattern, repl, string, count=0, flags=0) Return the string obtained by replacing the leftmost non-overlapping occurrences of the pattern in string by the replacement repl. repl can be either a string or a callable; if a string, backslash escapes in it are processed. If it is a callable, it's passed the match object and must return a replacement string to be used. import re >>> s = 'boys+.. and. girls+' >>> re.sub(r'[s.+]+', '', s) 'boy and girl' >>> re.sub(r'[s.+]+', '*', s) 'boy* and* girl*' >>> re.sub(r'[s.+]+', '*', s, 2) 'boy* and* girls+' ``` **3. re.split()正则拆分** ```python import re s = '123-456-789--101112' res = re.split(r'[-]+', s) print(res) ``` #### 02 | 条件与循环 1.判断是否为iterable类型 ```python >>> from collections import Iterable >>> isinstance('123', Iterable) True ``` 2.dict的不同遍历形式 ```angular2html >>> d = {'a': 1, 'b': 2, 'c': 3, 'd': 0} >>> d {'a': 1, 'b': 2, 'c': 3, 'd': 0} >>> for i in d: ... i ... 'a' 'b' 'c' 'd' >>> for i in d.values(): ... i ... 1 2 3 0 >>> for k, v in d.items(): ... k,v ... ('a', 1) ('b', 2) ('c', 3) ('d', 0) # 排序反转 >>> res = sorted(d.items(), key=lambda kv: kv[-1], reverse=True) >>> res [('c', 3), ('b', 2), ('a', 1), ('d', 0), ('A', -1)] ``` 3.思考题 ```python #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Desc: The demo of link attributes to values attributes = ['name', 'dob', 'bender'] values = [['jason', '2000-01-01', 'male'], ['mike', '2001-02-02', 'male'], ['nancy', '1997-07-07', 'female']] # Method 1 lst = [] for v in values: d = {} # 每次循环初始化一个空字典 for vi in range(len(v)): d[attributes[vi]] = v[vi] lst.append(d) print(lst) # Method 2 res = [{k: v for i, k in enumerate(attributes) for j,v in enumerate(vd) if i == j} for vd in values] print(res) # Method 3 res1 = [dict(zip(attributes, v)) for v in values] print(res1) ``` ### 17 | 装饰器 logger装饰器 ``` #!/usr/bin/env python3 # -*- coding: utf-8 -*- import time import os import functools from BaseLog import Log def logger(cur_file_name): def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): _logger = Log(cur_file_name).get_log() _logger.info('current function [%s] running ...' % func.__name__) start = time.time() func(*args, **kwargs) end = time.time() _logger.info('current function [%s] run over, spend time: %.4fs ' % (func.__name__, (end - start))) return wrapper return decorator if __name__ == '__main__': # 获取当前Python文件名 cur_file_name = os.path.basename(__file__) @logger(cur_file_name) def loop(num): for i in range(num): print(i) time.sleep(1) loop(4) ```