python版本信息
- Cpython:C语言写成;执行代码时,python代码会被转化为字节码;Cpython是一个字节码解释器。
- PyPy:由python写成的解释器;解释器的代码会先转化成C,然后再变异;比Cpython性能更好。因为Cpython把代码转化成字节码,PyPy把代码转化成机器码。
机器码(machine code),学名机器语言指令,有时也被称为原生码(Native Code),是电脑的CPU可直接解读的数据。
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。
字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是通过编译器和虚拟机器。编译器将源码编译成字节码,特定平台上的虚拟机器将字节码转译为可以直接执行的指令。
1. 语法基础
1.1 变量常量
-
常量:
- 数字:整数、长整数(取值范围为计算机支持的虚拟内存大小有关)、浮点数、复数
- 字符串:转义字符、三引号、Unicode字符串(国际通用字符编码方案,每一字符设定了统一且唯一的二进制编码)使用时
u"我是Unicoude字符串
- 布尔值:True、False
- None:空值常量
-
变量:内存中命名的存储位置,id()可查看其在内存的位置
-
变量强制类型转换
- 转为数字
a = "123" int(a) Out[8]: 123 int(a,8) Out[10]: 83 eval(a) Out[13]: 123 a = "print('hello')" eval(a) # 执行字符串中有效的python表达式 输出:hello
- 转为字符串
str(x) repr(obj) # 将对象转为字符串显示 chr(整数) # 将一个整数转为对应的ASCII的字符 ord(字符) # 将一个字符转为对应的ASCII class animal: def __init__(self,name): self.name=name cat = animal('maomi') repr(cat) Out[19]: '<__main__.animal object at 0x7f0f7fa11cc0>' chr(12) Out[20]: '\x0c' ord('a') Out[21]: 97
-
1.2 运算符
- 算数运算符:+ - * / ** % //
- 赋值运算符:= += -= *= /= %= **= //=
- 逻辑运算符:and or not
- 位运算:& | ^ ~ << >>
- 比较运算符:== != <>(!=) < > <= >=
- 字符串运算符:+ * [](索引) [start,end](切片) in not in r或者R(无转义)
1.3 赋值、分支、循环、异常
1.4 序列数据结构
-
list
- 元素类型可以相同也可不同
- 有索引和值两个属性,索引从0开始
- list.append list.insert l1+l2 list.reverse list.index(key)
-
tuple
- 内容不可变
-
dic
-
内容可变
-
键可以为字符串或整数,为不可变类型,即,为常量。
-
添加、删除、合并、判断是否存在元素、遍历字典、清空字典
d={ } d['name']='xiaoming' d['age']=23 d.pop('age') Out[51]: 23 d2 = { 'height':170} d.update(d2) 'age' in d Out[54]: False for key in d.keys(): print(key) name height for key,value in d.items(): print(key,value) name xiaoming height 170 d.clear()
-
-
set
-
无序排列的元素,分为可变集合(set)与不可变集合(frozenset)
-
可变集合可以添加元素、修改元素、删除元素
s = { 'python','java'} s Out[60]: { 'java', 'python'} s.add('c++') s Out[62]: { 'c++', 'java', 'python'} s.remove('java') s Out[64]: { 'c++', 'python'}
-
子集和超集
对于集合A、B,有关系操作符:
A==B A!=B A<B A<=B A>B A>=B
-
集合的合并
In [1]: s1= set([1,2]) In [2]: s2=set([1,2,3]) In [3]: s1 | s2 Out[3]: { 1, 2, 3} In [4]: s1.union(s2) Out[4]: { 1, 2, 3}
-
集合的交集
In [5]: s1&s2 Out[5]: { 1, 2} In [6]: s1.intersection(s2) Out[6]: { 1, 2}
-
集合的差集
In [7]: s1-s2 Out[7]: set() In [8]: s2-s1 Out[8]: { 3} In [9]: s1.difference(s2) Out[9]: set() In [10]: s2.difference(s1) Out[10]: { 3}
-
集合的对称差分:不同时属于集合A和集合B的元素
In [11]: s1^s2 Out[11]: { 3} In [12]: s1.symmetric_difference(s2) Out[12]: { 3}
-
2. 函数
-
函数体内可以使用全局变量;若需要在函数体内修改全局变量的值,需要使用关键字
global
;若只是访问全局变量的值,可以直接使用变量名访问。 -
将list和dict类型的变量最为参数传递,在函数体内可以修改其数据,即:修改后在全局生效。
-
参数的默认值。传递参数时,使用类似
times=1
的形式,使用函数的时候可以省略传入对应的参数。默认参数要置于参数列表后边。 -
可变长参数。可变长参数可以是元组或字典。
# 可变长参数最为元组 def sum(*t): res = 0 for i in range(0,len(t)-1): res+=t[i] return res # 可边长参数最为字典 def func(**t): print(t) print(sum(1,2,3)) func(c=3,d=4,e=5) #3 #{'c': 3, 'd': 4, 'e': 5}
2.1 常用内置函数
函数 | 原型 | 具体说明 |
---|---|---|
abs() | abs(x) | 返回 x 的绝对值 |
pow() | pow(x,y) | 返回 x 的 y 次幂 |
round() | round(x[,n]) | 返回浮点数 x 的四舍五入值,参数n指定保留的小数位数。如果省略n,则四舍五入保留整数部分 |
divmod() | divmod(a,b) | 返回 a 除以 b 的商和余数,返回一个元组。例如divmod(a,b)返回 (a / b, a % b) |
swapcase() | str.swapcase() | 将字符串str中的字母大小写互换 |
capitalize() | str.capitalize() | 将字符串str中的首字母大写,其余为小写 |
title() | str.title() | 将字符串str中每个词的首字母大写,其余为小写 |
find() | str.find(substr, [start, [end]]) | 返回字符串str中出现子串substr的第一个字母的位置,如果str中没有substr,则返回-1。搜索范围从start至end |
index() | str.index(substr, [start, [end]]) | 与find()函数相同,只是在str中没有substr时,index()函数会返回一个运行时错误 |
rfind() | str.rfind(substr, [start, [end]]) | 返回从右侧算起,字符串str中出现子串substr的第一个字母的位置,如果str中没有substr,则返回-1。搜索范围从start至end |
rindex() | str.rindex (substr, [start,[end]]) | 与rfind()函数相同,只是在str中没有substr时,rindex()函数会返回一个运行时错误 |
count() | str.count(substr, [start,[end]]) | 计算substr在str中出现的次数。统计范围从start至end |
replace() | str.replace(oldstr,newstr, [count]) | 把str中的oldstr替换为newstr,count为替换次数 |
strip() | str.strip([chars]) | 把字符串str中前后chars中有的字符全部去掉。如果不指定参数chars,则会去掉空白符(包括’\n’, ‘\r’, ‘\t’和’ ') |
lstrip() | str.lstrip([chars]) | 把字符串str中前面包含的chars中有的字符全部去掉。如果不指定参数chars,则会去掉空白符(包括’\n’, ‘\r’, ‘\t’和’ ') |
rstrip() | str.rstrip([chars]) | 把字符串str中后面包含的chars中有的字符全部去掉。如果不指定参数chars,则会去掉空白符(包括’\n’, ‘\r’, ‘\t’和’ ') |
expandtabs() | str.expandtabs([tabsize]) | 把字符串str中的tab字符替换为空格,每个tab替换为tabsize个空格,默认是8个 |
startswith() | str. startswith(substr) | 判断str是否以substr开头 |
endswith() | str.endswith(substr) | 判断str是否以substr为结尾 |
isalnum() | str.isalnum() | 判断str是否全为字母或数字 |
isalpha() | str.isalpha() | 判断str是否全为字母 |
isdigit() | str.isdigit() | 判断str是否全为数字 |
islower() | str.islower() | 判断str是否全为小写字母 |
isupper() | str.isupper() | 判断str是否全为大写字母 |
详细参见博客link
3. 面向对象
3.1 静态变量和静态方法
静态变量和静态方法属于类,与对象无关。访问静态变量的方法:类名.变量名
。当然可以通过对象访问静态变量。通过类名访问静态变量与通过对象名访问静态变量的实例不同,且互不干扰。
class Animal:
num = 0
def __init__(self,name):
self.name = name
Animal.num+=1
def __del__(self):
Animal.num-=1
cat = Animal('1')
dog = Animal('2')
print(Animal.num) # 2
print(cat.num) # 2
cat.num+=1
print(cat.num) # 3
print(Animal.num) # 2
print(dog.num)# 2
del cat
print(Animal.num) # 1
静态方法只属于定义它的类,不属于对象。具有如下特点:
- 无须传入self参数,因此在静态方法中无法访问实例变量。
- 在静态方法中不可以直接访问类的静态变量,但是可以通过类名引用静态变量。
可以通过对象名调用静态方法,也可以通过类名调用静态方法。两种方法无区别。
class Animal:
num = 0
def __init__(self,name):
self.name = name
Animal.num+=1
def __del__(self):
Animal.num-=1
def eat(self):
print('eatitng')
@staticmethod
def animal_nums():
""" docstring """
print('staticmethod')
print(Animal.num)
pass
cat = Animal('1')
dog = Animal('2')
cat.animal_nums()
Animal.animal_nums()
# output
# staticmethod
# 2
# staticmethod
# 2
3.2 类方法
类方法的特点:
- 与静态方法一样,类方法可以使用类名调用类方法
- 与静态变量一样,类成员方法无法访问实例变量,但可以访问类的静态变量
- 类方法需传入代表本类的cls参数。可以通过cls访问类的静态变量。
class Animal:
num = 0
def __init__(self,name):
self.name = name
Animal.num+=1
def __del__(self):
Animal.num-=1
def eat(self):
print('eatitng')
@staticmethod
def animal_nums():
""" docstring """
print('staticmethod')
print(Animal.num)
pass
@classmethod
def get_nums(cls):
print('staticmethod')
print(cls.num)
cat = Animal('1')
dog = Animal('2')
cat.get_nums()
Animal.get_nums()
# output
# classmethod
# 2
# classmethod
# 2
3.3 继承
子类可以继承父类的成员方法和成员变量(即:所有属性和函数)。
class Cat(Animal):
def crawl(self):
print('cat is crawling')
def sing(self):
print("miao~~")
dog = Animal('2')
cat = Cat('1')
cat.animal_nums()
cat.get_nums()
cat.sing()
dog.crawl()
cat.crawl()
# staticmethod
# 2
# classmethod
# 2
# miao~~
# cat is crawling
3.4 抽象类
抽象类是包含抽象方法的类,抽象方法不包含任何实现的代码,只能在子类中实现抽象函数的代码。
-
定义抽象类
通过类库实现抽象类。元类:创建类的类。
from abc import ABCMeta,abstractclassmethod class myabc(object): __metaclass__ = ABCMeta @abstractclassmethod def abcmethod(self): pass
3.5 多态
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
from abc import ABCMeta,abstractclassmethod
class Shape(object):
__metaclass__ = ABCMeta
def __init__(self):
self.color = 'black'
@abstractclassmethod
def draw(self):
pass
class circle(Shape):
def __init__(self,x,y,r):
self.x=x
self.y=y
self.r=r
def draw(self):
print("Draw circle:(%d ,%d ,%d)"%(self.x,self.y,self.r))
class line(Shape):
def __init__(self,x1,y1,x2,y2):
self.x1=x1
self.y1=y1
self.x2=x2
self.y2=y2
def draw(self):
print("Draw line:(%d ,%d ,%d,%d)"%(self.x1,self.y1,self.x2,self.y2))
c = circle(10,10,5)
c.draw()
l=line(10,10,20,20)
l.draw()
# Draw circle:(10 ,10 ,5)
# Draw line:(10 ,10 ,20,20)
4. 模块
将函数按功能划分到一起,以便日后使用或共享给他人。
-
sys模块
sys.argv #获取命令行参数列表,第一个元素是程序本身 sys.exit(n) #退出Python程序,exit(0)表示正常退出。当参数非0时,会引发一个SystemExit异常,可以在程序中捕获该异常 sys.version #获取Python解释程器的版本信息 sys.maxsize #最大的Int值,64位平台是2**63 - 1 sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 sys.platform #返回操作系统平台名称 sys.stdin #输入相关 sys.stdout #输出相关 sys.stderr #错误相关 sys.exc_info() #返回异常信息三元元组 sys.getdefaultencoding() #获取系统当前编码,默认为utf-8 sys.setdefaultencoding() #设置系统的默认编码 sys.getfilesystemencoding() #获取文件系统使用编码方式,默认是utf-8 sys.modules #以字典的形式返回所有当前Python环境中已经导入的模块 sys.builtin_module_names #返回一个列表,包含所有已经编译到Python解释器里的模块的名字 sys.copyright #当前Python的版权信息 sys.flags #命令行标识状态信息列表。只读。 sys.getrefcount(object) #返回对象的引用数量 sys.getrecursionlimit() #返回Python最大递归深度,默认1000 sys.getsizeof(object[, default]) #返回对象的大小 sys.getswitchinterval() #返回线程切换时间间隔,默认0.005秒 sys.setswitchinterval(interval) #设置线程切换的时间间隔,单位秒 sys.getwindowsversion() #返回当前windwos系统的版本信息 sys.hash_info #返回Python默认的哈希方法的参数 sys.implementation #当前正在运行的Python解释器的具体实现,比如CPython sys.thread_info #当前线程信息
-
platform模块
import platform print(platform.platform()) print(platform.version()) print(platform.machine()) # Linux-5.4.0-58-generic-x86_64-with-glibc2.29 # 64-Ubuntu SMP Wed Dec 9 08:16:25 UTC 2020 # x86_64 print(platform.node()) print(platform.uname()) # more information print(platform.python_compiler()) #GCC 9.3.0 print(platform.python_implementation())
-
math模块
函数 数学表示 含义 .pi 圆周率π π的近似值,15位小数 .e 自然常数 e e的近似值,15位小数 ceil(x) [x] 对浮点数向上取整 floor(x) [x] 对浮点数向下取整 pow(x, y) x^y 计算x的y次方 log(x) log x 以e为基数的对数 log10(x) log10x 以10为基数的对数 sqrt(x) √x 平方根 exp(x) e的x次幂 degrees(x) 将弧度值转换为角度值 radians(x) 将角度值转换为弧度值 sin(x) sin x 正弦函数 cos(x) cos x 余弦函数 tan(x) tan x 正切函数 asin(x) arcsin x 反正弦函数,x∈[-1.0, 1.0] acon(x) arccon x 反余弦函数,x∈[-1.0, 1.0] atan(x) arctan x 反正切函数,x∈[-1.0, 1.0] -
random模块
方法 原型 具体说明 random random.random() 生成一个0到1的随机浮点数: 0 <= n < 1.0 uniform random.uniform(a,b) 用于生成一个指定范围内的随机浮点数,两个参数其中一个是上限,另一个是下限。如果a < b,则生成的随机数n满足a <= n <= b。如果 a > b, 则b <= n <= a randint random.randint(a,b) 用于生成一个指定范围内的整数。其中参数a是下限,参数b是上限,生成的随机数n: a <= n <= b randrange random.randrange([start],stop[,step]) 从[start,stop)范围内,按指定步长step递增的集合中获取一个随机数。如:random.randrange(1,10,2),结果相当于从[1,3,5,7,9]序列中获取一个随机数 choice random.choice(sequence) 从序列中获取一个随机元素。参数sequence表示一个有序类型,可以是列表、元组或字符串 shuffle random.shuffle(x) 用于将一个列表中的元素打乱。x是一个列表 sample random.sample(sequence,k) 从指定序列中随机获取k个元素,以列表类型返回。原有序列不会被修改 import random print(random.random()) # 0.3653578594153011 print(random.uniform(1,5)) # 4.236615556614723 print(random.randint(1,5)) # 1 l = [i for i in range(1,11)] print(random.randrange(1,10,2)) # 7 print(random.choice(l)) # 6 random.shuffle(l) print(l) # [4, 6, 8, 2, 7, 3, 10, 5, 1, 9] print(random.sample(l,3)) # [1, 4, 8]
-
decimal模块
用于浮点计算。因为float缺乏精确性。Decimal数据类型更加适合金融应用和其他需要精确十进制表达的情况。小数点精度默认28。
from decimal import Decimal print(Decimal('1.0')/Decimal('3.0')) from decimal import getcontext getcontext().prec=6 # set precision print(Decimal('1.0')/Decimal('3.0')) # 0.3333333333333333333333333333 # 0.333333
-
fractions模块
fractions模块用于表现和处理分数。
from fractions import Fraction x = Fraction(1,3) print(x) print(x*2) # 1/3 # 2/3
-
time模块
import time print(time.time()) #1609596393.0491743 print(time.localtime(time.time())) # time.struct_time(tm_year=2021, tm_mon=1, tm_mday=2, tm_hour=22, tm_min=7, tm_sec=11, tm_wday=5, tm_yday=2, tm_isdst=0) print(time.strftime('%Y-%m-%d,%H:%M:%S',time.localtime(time.time()))) # 2021-01-02,22:11:49 print(time.ctime()) # Sat Jan 2 22:12:23 2021
5. 函数式编程
5.1 函数式编程简介
函数式编程将计算过程看做是数学函数,也就是可以使用表达式编程。
头等函数:指在程序设计语言中,函数被当作头等公民。这意味着,函数可以作为别的函数的参数、函数的返回值,赋值给变量或存储在数据结构中。
高阶函数:是头等函数的一种实践,它可以将其他函数作为参数或返回结果的函数。
纯函数:(1)纯函数与外界交换数据只有唯一的渠道:参数和返回值。(2)对于同一个输入,输出结果都相同。(3)纯函数不操作全局变量,没有状态,无I/O操作,不改变传入的任何参数的值。理想情况下,不会给他传入任何外部数据。
函数式编程的优点:
- 便于进行单元检测
- 便于调试
- 适合并行执行
5.2 函数式编程常用的函数
5.2.1 lambda表达式
一种匿名函数,只能有唯一的一条语句。
返回函数名= lambda x,y,z : x+y+z
sum = lambda x,y,z : x+y+z
print(sum(1,2,3))
Arr = [(lambda x: x**2),(lambda x: x**3),(lambda x: x**4)]
for i in Arr:
print(i(2),end=' ')
# 4 8 16
5.2.2 map()函数
map函数将指定序列中的所有元素作为参数传入指定的函数,并将结果构成一个新的序列返回。
arr = map(lambda x: x**2,[1,2,3])
for i,value in enumerate(arr):
print(i,value)
# 0 1
# 1 4
# 2 9
5.2.3 filter()函数
可以对指定序列进行过滤操作。将function返回为True对应的参数保留。function只能返回True或False。
filter(function,sequence)
def fu(x):
if x%2 == 0:
return True
else:
return False
l = filter(fu,[i for i in range(20)])
for i in l:
print(i,end=' ')
# 0 2 4 6 8 10 12 14 16 18
5.2.4 reduce()函数
将序列中的元素作为参数,按一定的规则(将第一个元素和第二个元素作为参数传入得到的结果与第三个参数一起作为输入,以此类推)调用指定函数。
from functools import reduce
def myadd(x,y):
return x+y
sum = reduce(myadd,[i for i in range(5)])
print(sum)
5.2.5 zip()函数
以一系列列表作为参数,将参数列表中对应元素打包成一个元组,返回元组列表。
l1 = [i for i in range(1,11)]
l2 = [i for i in range(2,12)]
zip_ = zip(l1,l2)
for i in zip_:
print(i)
# (1, 2)
# (2, 3)
# (3, 4)
# (4, 5)
# (5, 6)
# (6, 7)
# (7, 8)
# (8, 9)
# (9, 10)
# (10, 11)
5.2.6 普通编程与函数式编程
l = [2,-6,11,-7,8,15]
sum = 0
for i in range(len(l)):
if l[i]>0:
sum+=l[i]
print(sum)
# 36
l = [2,-6,11,-7,8,15]
nums = filter(lambda x: x>0,l)
from functools import reduce
sum = reduce(lambda x,y: x+y,nums)
print(sum)
# 36
函数式编程的特点:
- 代码更简单
- 数据、操作、返回值都放在一起
- 没有循环体,几乎没有临时变量
- 代码用来描述要做什么,而不是怎么去做
5.3 闭包与递归函数
闭包(closure):指函数的潜逃。可以在函数内部定义一个嵌套函数,将嵌套函数视为一个对象,可以将该对象作为函数的返回结果。
def func_lib():
def myadd(x,y):
return x+y
return myadd
fadd = func_lib()
print(fadd(2,6))
# 8
递归函数就是在函数体内直接或者间接调用函数本身。
5.4 迭代器与生成器
5.4.1 迭代器
迭代器是访问元素的一种方式。从可迭代对象的第一个元素开始访问,不可回退,只能往前迭代。
-
iter()函数
使用该函数获取序列的迭代器对象。
迭代器对象=iter(序列对象)``````next(迭代器对象)
获取迭代器的下一个元素。l = [i for i in range(1,100)] iter_ = iter(l) print(next(iter_)) # 1 print(next(iter_)) # 2
-
enumerate()函数
将可迭代对象生成一个有序号的序列。
dic_ = { '1':'a','2':'b'} for index,key in enumerate(dic_): print(index,key)
5.4.2 生成器
生成器是一个特殊的函数,具有如下特点:
- 生成器函数都包含一个yield语句,当执行到yield语句时函数返回
- 生成器函数可以记住上一次返回时在函数体中的位置,对生成器函数的下一次调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
def addlist(l:list):
for i in l :
yield i+1
l = [i for i in range(1,10)]
for i in addlist(l):
print(i,end=' ')
生成器的返回值有一个__next__()
方法,它可以恢复生成器执行,直到下一个yield表达式处。
def addlist(l:list):
for i in l :
yield i+1
l = [i for i in range(1,10)]
x= addlist(l)
a=x.__next__()
print(a) # 2
b=x.__next__()
print(b) # 3