个人学习python的笔记!基于 python3 ! 相关文档可以参考: https://docs.python.org/zh-cn/3/library/index.html , 本地可以执行python3 -m pydoc -p 1234
打开文档
基本语法 1. 简单控制语句 字符串推荐用 ''
单引号引用
1 2 3 4 5 6 7 8 9 10 11 12 list : List [int ] = [1 , 2 , 3 ]for elem in list : if elem > 1 : print (f'data {elem} > 1' ) else : print (f'data {elem} < 1' ) ''' data 1 < 1 data 2 > 1 data 3 > 1 '''
2. 异常 1 2 3 4 5 6 7 8 9 x = -1 try : if x < 0 : raise Exception("Sorry, no numbers below zero" ) except Exception as err: print ("find err: %s" % err) ''' find err: Sorry, no numbers below zero '''
3. 推导式(比较晦涩难懂) 推导式好处: 效率更高,底层是c执行
1. 列表推导式 一共两种形式:(参考: https://zhuanlan.zhihu.com/p/139621170 ) , 它主要是输出是列表(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 import re""" 获取所有的数字 """ list = ["1" , "2" , "3" , "4" , "5" , "a" , "b" , "c" ]print ([elem for elem in list if re.match("\\d" , elem)])''' ['1', '2', '3', '4', '5'] ''' """ 获取所有的字母 """ print ([elem for elem in list if re.match("[a-z]" , elem)])''' ['a', 'b', 'c'] ''' """ 如果元素是数字则存储,否则则upper """ print ([elem if re.match("\\d" , elem) else elem.upper() for elem in list ])''' ['1', '2', '3', '4', '5', 'A', 'B', 'C'] '''
最佳实践: 参考(https://github.com/httpie/httpie/blob/master/httpie/core.py#L235 )
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 41 42 43 44 45 46 47 48 def decode_raw_args ( args: List [Union [str , bytes ]], stdin_encoding: str ) -> List [str ]: """ Convert all bytes args to str by decoding them using stdin encoding. """ return [ arg.decode(stdin_encoding) if type (arg) is bytes else arg for arg in args ] def decode_raw_args_parse ( args: List [Union [str , bytes ]], stdin_encoding: str ) -> List [str ]: """ Convert all bytes args to str by decoding them using stdin encoding. 不使用推导式 """ result: List [str ] = [] for arg in args: if type (arg) is bytes : result.append(arg.decode(stdin_encoding)) else : result.append(arg) return result print (decode_raw_args(args=[b'111' , b'222' ], stdin_encoding="utf-8" ))print (decode_raw_args(args=["111" , "222" ], stdin_encoding="" ))''' ['111', '222'] ['111', '222'] ''' print (decode_raw_args_parse(args=[b'111' , b'222' ], stdin_encoding="utf-8" ))print (decode_raw_args_parse(args=["111" , "222" ], stdin_encoding="" ))''' ['111', '222'] ['111', '222'] '''
2. 字典推导式 { key_expr: value_expr for value in collection if condition }
,输出是 dict
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 """ { key_expr: value_expr for value in collection if condition } 反转key value,且获取 value 为在set {'a', 'b', 'c'}中的元素 """ dict_old = {'a' : 'A' , 'b' : 'B' , 'c' : 'C' , 'd' : 'D' } print ({dict_old[value]: value for value in dict_old if value in {'a' , 'b' , 'c' }})''' {'A': 'a', 'B': 'b', 'C': 'c'} ''' print ({key: value for value, key in dict_old.items() if value in {'a' , 'b' , 'c' }})''' {'A': 'a', 'B': 'b', 'C': 'c'} '''
3. 集合推导式 表达式:
{ expr for value in collection if condition }
{exp1 if condition else exp2 for x in data}
输出是 set
其实就是上面列表推导式 []
换成 {}
,输出由 list
变成了 set
4. for 循环 迭代器 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 osfrom collections.abc import Iterablewith open ("text.log" , "wt" ) as file: file.truncate() file.writelines("line 1" + os.linesep) file.writelines("line 2" + os.linesep) file.writelines("line 3" + os.linesep) pass with open ("text.log" , "rt" ) as file: for line in file: print ("type: {type}, isinstance: {isinstance}, line: {line}" .format (type =type (file), isinstance =isinstance (file, Iterable), line=line)) pass ''' type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 1 type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 2 type: <class '_io.TextIOWrapper'>, isinstance: True, line: line 3 '''
这里面 _io.TextIOWrapper
实现了 __next__()
方法
比如我们自己实现一个可迭代的对象
下面可以看到我使用了类型申明 List[str]
其实这个python运行时并不会检测,需要工具进行检测!
变量默认都是 Any
类型 ,具体可以看 https://docs.python.org/zh-cn/3/library/typing.html
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 from typing import List class Items (object ): def __init__ (self, list : List [str ] ): self.list = list self.index = 0 def __next__ (self, *args, **kwargs ): """ next,没有抛出StopIteration """ if self.index >= len (self.list ): raise StopIteration result = self.list [self.index] self.index = self.index + 1 return result def __iter__ (self, *args, **kwargs ): """ 返回一个迭代器 """ return self data = Items(["1" , "2" , "3" ]) for x in data: print (x) ''' 1 2 3 '''
5. 包管理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 from ..a import foo from .a import foo_a import sys from copy import deepcopy from pygments.formatters.terminal import TerminalFormatter import demo.utils.adef c_foo (): demo.utils.a.foo_a() TerminalFormatter() deepcopy() print (sys.api_version) def b_foo (): foo()
基本数据类型 1. 定义方式 mylist: list[str] = ["apple", "banana", "cherry"]
mylist=["apple", "banana", "cherry"]
Text Type: str
Numeric Types: int
, float
, complex
Sequence Types: list
, tuple
, range
Mapping Type: dict
Set Types: set
, frozenset
Boolean Type: bool
Binary Types: bytes
, bytearray
, memoryview
2. 数字基本类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 x = 1 y = 1.1 z = 1j a = complex (1 , 2 ) print (type (x))print (type (y))print (type (z))print (z.imag, z.real)print (type (a))print (a.imag, a.real)''' <class 'int'> <class 'float'> <class 'complex'> 1.0 0.0 <class 'complex'> 2.0 1.0 '''
3. 字符串 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 41 42 43 44 45 46 47 48 49 50 51 52 str = "hello" print (str )print (str [0 :])print (str [:5 ])print (str [:-1 ])print (str [0 :5 ])print (str [0 :5 :1 ])print (str [0 :5 :2 ])''' hello hello hello hell hello hello hlo ''' print ("My name is {} and age is {}" .format ("tom" , 18 ))''' My name is tom and age is 18 ''' quantity = 3 itemno = 567 price = 49.95 myorder = "I want to pay {2} dollars for {0} pieces of item {1}." print (myorder.format (quantity, itemno, price))''' I want to pay 49.95 dollars for 3 pieces of item 567. ''' str = "hello world! " print (str .upper())print (str .lower())print (str .strip())print (str + " ..." )''' HELLO WORLD! hello world! hello world! hello world! ... ''' myorder = "I have a {carname}, it is a {model}." print (myorder.format (carname="Ford" , model="Mustang" ))''' I have a Ford, it is a Mustang. '''
4. lambda 其实就是一个func
1 2 3 4 5 6 7 8 def add (num ): return lambda x: x + num print (add(10 )(10 ))''' 20 '''
lanbda 例子2
1 2 3 4 5 6 7 8 9 10 11 12 import jsonclass Obj : def __init__ (self ): self.name = "tom" self.age = 1 print (json.dumps(Obj(), default=lambda obj: obj.__dict__))''' {"name": "tom", "age": 1} '''
集合 list
, tuple
, range
, dict
, set
, frozenset
list , 例如: mylist = ["apple", "banana", "cherry"]
tuple 是特殊的数组,就是不能改变, 例如 mytuple = ("apple", "banana", "cherry")
range 可以理解是个迭代器, 例如: dict 就是个map, 例如: thisdict = {"brand": "Ford", "model": "Mustang", "year": 1964}
set 就是个去重复的list , 例如: myset = {"apple", "banana", "cherry"}
1. 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 mylist = ["apple" , "banana" , "cherry" ] print (mylist[0 ])print (mylist[2 ])print (mylist[-1 ])print (mylist[0 :3 :2 ])''' apple cherry cherry ['apple', 'cherry'] ''' mylist.append("orange" ) print (mylist)''' ['apple', 'banana', 'cherry', 'orange'] ''' mylist.insert(0 , "mango" ) print (mylist)''' ['mango', 'apple', 'banana', 'cherry', 'orange'] ''' for x in mylist: print (x) ''' apple banana cherry orange ''' for index in range (len (mylist)): print ("index: %d" % index) ''' index: 0 index: 1 index: 2 index: 3 index: 4 ''' if "apple" in mylist: print ("success!" ) ''' success! ''' new_list = [elem.upper() for elem in mylist if "a" in elem] print (new_list)''' ['MANGO', 'APPLE', 'BANANA', 'ORANGE'] ''' newList = [] for elem in mylist: if 'a' in elem: newList.append(elem.upper()) print (newList)''' ['MANGO', 'APPLE', 'BANANA', 'ORANGE'] '''
2. map 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 thisdict = {"brand" : "Ford" , "model" : "Mustang" , "year" : 1964 } for key, value in thisdict.items(): print ("key: {}, value: {}" .format (key, value)) ''' key: brand, value: Ford key: model, value: Mustang key: year, value: 1964 ''' for key in thisdict: print ("key: {}, value: {}" .format (key, thisdict[key])) ''' key: brand, value: Ford key: model, value: Mustang key: year, value: 1964 '''
3. range 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 for x in range (6 ): print ("x is %d" % x) ''' x is 0 x is 1 x is 2 x is 3 x is 4 x is 5 ''' for x in range (2 , 6 ): print ("x is %d" % x) ''' x is 2 x is 3 x is 4 x is 5 ''' for x in range (1 , 6 , 2 ): print ("x is %d" % x) ''' x is 1 x is 3 x is 5 '''
方法 1. 定义一个空方法 1 2 3 4 5 def func_1 (): pass func_1()
2. 参数 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 def func_1 (name, age=1 , *args, **kwargs ): print ("name: %s" % name) print ("age: %d" % age) print ("len(args): {}, type: {}" .format (len (args), type (args))) for value in args: print ("args value: {}" .format (value)) print ("len(kwargs): {}, type: {}" .format (len (kwargs), type (kwargs))) for key, value in kwargs.items(): print ("kwargs key: {}, value: {}" .format (key, value)) func_1(name="tom" , age=10 , args="1" , kwargs="2" ) ''' name: tom age: 10 len(args): 0 len(kwargs): 0, type: <class 'tuple'> len(kwargs): 2, type: <class 'dict'> kwargs key: args, value: 1 kwargs key: kwargs, value: 2 ''' func_1("tom" , 10 , "1" , "2" , args="1" , kwargs="2" ) ''' name: tom age: 10 len(args): 2, type: <class 'tuple'> args value: 1 args value: 2 len(kwargs): 2, type: <class 'dict'> kwargs key: args, value: 1 kwargs key: kwargs, value: 2 '''
3. 类型 申明输入输出类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from typing import List , Union def decode_raw_args ( args: List [Union [str , bytes ]], stdin_encoding: str ) -> List [str ]: """ Convert all bytes args to str by decoding them using stdin encoding. """ return [ arg.decode(stdin_encoding) if type (arg) is bytes else arg for arg in args ]
类 1. 定义类和方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class Person (object ): gender = "none" def __init__ (self, name, age ): self.name = name self.age = age def my_name (self ): return self.name p = Person(name="tome" , age=1 ) print (p.my_name())
2. 类型的继承 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 import json class Person(object): # gender none, male or female gender = "none" # 构造器 def __init__(self, name, age): self.name = name self.age = age def my_name(self): return self.name p = Person(name="tome" , age=1 ) print(p.my_name()) class Mail(Person): def __init__(self, name, age): super(Mail, self).__init__(name, age) self.gender = "mail" def my_name(self): return self.name + "_mail" p = Mail(name="tome" , age=1 ) print(json.dumps(p, default=lambda obj: obj.__dict__)) print(p.my_name())
3. 类 __new__
函数 主要是__init__
执行前会调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import jsonclass Person (object ): def __new__ (cls, *args, **kwargs ): instance = object .__new__(cls) instance.job = "it" return instance def __init__ (self, name, age ): self.name = name self.age = age def to_json (self ): return json.dumps(self, default=lambda obj: obj.__dict__) p = Person(name="tome" , age=1 ) print (p.to_json())
其他用法技巧 1. 断言 1 2 3 4 5 6 if type (1 ) is int : print ("args is int" ) ... ''' args is int '''
2. 测试 <<<
可以参考文件: https://segmentfault.com/q/1010000010389542 , 属于doctest
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 41 42 def humanize_bytes (n, precision=2 ): """Return a humanized string representation of a number of bytes. >>> humanize_bytes(1) '1 B' >>> humanize_bytes(1024, precision=1) '1.0 kB' >>> humanize_bytes(1024 * 123, precision=1) '123.0 kB' >>> humanize_bytes(1024 * 12342, precision=1) '12.1 MB' >>> humanize_bytes(1024 * 12342, precision=2) '12.05 MB' >>> humanize_bytes(1024 * 1234, precision=2) '1.21 MB' >>> humanize_bytes(1024 * 1234 * 1111, precision=2) '1.31 GB' >>> humanize_bytes(1024 * 1234 * 1111, precision=1) '1.3 GB' """ abbrevs = [ (1 << 50 , 'PB' ), (1 << 40 , 'TB' ), (1 << 30 , 'GB' ), (1 << 20 , 'MB' ), (1 << 10 , 'kB' ), (1 , 'B' ) ] if n == 1 : return '1 B' for factor, suffix in abbrevs: if n >= factor: break return f'{n / factor:.{precision} f} {suffix} '
3. yield 其实类似于程序的断电,比如程序运行到那里其实是返回一个生成器,然后当你下一步是才会执行,比较节省内存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 from typing import List def new (size: int = 1024 * 1024 ): yield new_data(size) def new_data (size: int ) -> List [int ]: return [0 ] * size data = new() print (type (data))print (len (next (data))) ''' <class 'generator'> 1048576 '''
脚本 base64输出 1 2 3 4 5 6 7 echo "aGVsbG8gcHl0aG9uCg==" | python -c "import sys,base64; print(sys.stdin.read())" -> echo "aGVsbG8gcHl0aG9uCg==" | python -c "import sys,base64; print(base64.b64decode(sys.stdin.read()))" -> stdout: b'hello python\n'
文件操作 r
, w
, x
,a
四种类型(a: append, w=truncate+create, x=truncate+create if not exit)b
,t
文件类型第一列可以和第二列文件类型组合,第一列不允许并存
1 2 3 4 5 6 7 8 9 10 11 import oswith open ("file.log" , "w" ) as file: for x in range (0 , 100 ): file.write("hello world" +os.linesep) with open ("file.log" ,"r" ) as file: for line in file.readlines(): print (line)
json 1 2 3 4 import jsonprint (json.dumps({"k1" : "v1" , "k2" : [1 , 2 , 3 ]}))print (json.loads('{"k1": "v1", "k2": [1, 2, 3]}' ))
如果是class,需要继承 JSONEncoder和JSONDecoder实现子类
,或者
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import json, datetimeclass Demo (object ): def __init__ (self, name: str , age: int , birthday: datetime.date ): self.name = name self.agw = age self.birthday = birthday def to_json (self, _ ): return {"name" : self.name, "age" : self.agw, "birthday" : self.birthday.strftime("%Y-%m-%d" )} data = Demo("tom" , 18 , datetime.date(2001 , 1 , 1 )) print (json.dumps(data, default=data.to_json))
typing (申明类型) 官方文档: https://docs.python.org/zh-cn/3/library/typing.html
可以参考这篇文章: https://sikasjc.github.io/2018/07/14/type-hint-in-python/
对于喜欢静态类型的语言,我觉得是非常nice的
1 2 3 4 5 6 7 8 from typing import Dict , List def test (data: Dict [str , str ] ) -> List [str ]: return [x for x in data] print (test({"k1" : "v1" , "k2" : "v2" }))