Python学习片段笔记1
集合的创建:
集合只能通过set()进行创建,无法用{}直接创建
软件开发流程
1、What 做什么-分析
2、How 怎么做-设计
3、Do it 开始做-执行
4、Test 测试-测试与修复错误
5、Use 使用-操作或开发
6、Maintain 维护-改进
format
age=20 name='Swaroop' print('{} was {} years old when he wrote this book'.format(name,age))
一些特殊意义:
转义字符:\,其也可用于显式行连接
s='This is a string. \ This continues the string.' print(s)
global:
若使用函数外的全局变量,需要在使用前声明该变量为全局变量。
x=50 def func(): global x print('x is',x)
可变参数
当我们声明一个例如*param的参数时,从此处开始直到结束的所有位置参数都将被收集并汇集成一个元组。同时它是可以遍历的,跟正常元组无异。
类似,**param,从此处开始直至结束的所有参数都将被收集并汇集成一个字典。
def total(a=5,*numbers,**phonebook): prinbt('a',a) #遍历元组所有项目 for single_item in numbers: print('single_item',single_item) #遍历字典中所有项目 for first_part,second_part in phonebook.items(): print(first_part,second_part) print(total(10,1,2,3,jack=1123,john=2231,inge=1560)) 输出: a 10 single_item 1 single_item 2 single_item 3 inge 1560 john 2231 jack 1123 None
Docstrings
python3有两种注释方式,一种是# 另外一种是3引号,引号又分为单引和双引,一般的编译器会有明显的标识,#注释显示的为灰色,而引号显示的为绿色。
引号产生的注释就算做Docstring。可通过以下属性直接访问:
def func(): #we can not see it """we can see it""" '''we can see it ,too''' pass print(func().__doc__)
值得一提的是,models和class同样适用该属性
数据结构的深拷贝
深拷贝浅拷贝的意义自不必多说,问题在于如何进行,通常我们在进行数据处理时,经常遇到这种问题,本想存储原数据结构然后对原数据机构进行操作修改,结果两者都进行了变化,那我门如何进行深拷贝呢?
第一种方法,直接用copy包:
import copy a=5 b=copy.deepcopy(5) a=4 print(a,b)
第二种,切片,这种方法比较局限,只能用于列表元组字符串:
s0='web' a=s0 del s0[0] print(s0,a) s1='body' b=s1[:] del s1[0] print(s1,b)
另外,切片还可用于翻转以上几种数据结构的顺序:
string='abc' lst=[1,2,3] tup=(1,2,3) print(string[::-1]) print(lst[::-1]) print(tup[::-1])
关于字符串的一些可用函数
name='Swaroop' if name.startswith('Swa'): print('Yes, the string starts with Swa') if 'a' in name: print('Yes, it contains the string a') if name.find('war') != -1: print('Yes , it contains the string war') delimiter='_*_' mylist=['a','b','c'] print(delimiter.join(mylist))
输出:
Yes , the string starts with Swa
Yes , it contains the string a
Yes , it contains the string war
a_*_b_*_c
类
__init__
class Person: def __init__(self,name): self.name=name
属性
变量分为类变量和对象变量
class Robot: population=0 def __init__(self,name): self.name=name @classmethod def show_name(self): print(self.name)
population属于类变量,name属于对象变量。这里与C是有一定区别的,其中,通过装饰器将show_name标记为类方法。
可以将装饰器想象为调用一个包装器,@classmethod等价于
show_name = classmethod(show_name)
私有变量
所有的类成员均是公开的,如果我们对某个变量有私有的要求,可以在命名新的数据成员时,在名称前加双下划线,非用此方法的均对外公开。
继承
class SchoolMember: def __init__(self, name, age): pass class Teacher(SchoolMember): def __init__(self,name,age,salary): SchoolMember.__init__(self,name,age) class Student(SchoolMember): def __init__(self,name,age,marks): SchoolMember.__init__(self,name,age)
这里记录一下python的继承方式以及父类子类之间构造函数的关系,另外,涉及多重继承,python依旧是深度优先遍历。
闭包
闭包条件,函数内的函数,内函数引用外函数的局部变量。目的,减少全局变量的使用,更具有封装性。
为什么呢?
这首先取决于Python的一个特性,如果函数有默认参数,那么它只会在本次程序的开始初始化一次,也就是说,它相当于这个函数内部的静态变量。那么我们在这场游戏中,行走时便可以保持一个持续移动的状态,而非在一段距离内回流。
1 #一个游戏内人物行走栗子 2 3 x_max=100 4 x_min=-100 5 y_max=100 6 y_max=-100 7 8 def creat(x=0,y=0): #xy代表初始位置 9 def walk(D,step): #D代表方向,1左(上)-1右(下)0不动 10 nonlocal x,y 11 x+=D[0]*step 12 y+=D[1]*step 13 if x>x_max: 14 x=200-x 15 elif x<x_min: 16 x=-100-x 17 if y>y_max: 18 y=200-y 19 elif y<y_min: 20 y=-100-y 21 return walk
另,一般设计程序时,本着一个函数只做一件事的原则,那么闭包也会派上用场。
装饰器
这也是闭包的应用,不过引出这个是为了引出另外一个新内容。@装饰器
1 def log(func): 2 def wrapper(): 3 print("begin to run the function of eat()") 4 func() 5 print("end to run the function of eat()") 6 return wrapper 7 def eat(): 8 print("I'm eating!") 9 10 >>log(eat)
def log(func): def wrapper(): print("begin to run the function of eat()") func() print("end to run the function of eat()") return wrapper @log def eat(): print("I'm eating!") >>eat()
引入装饰器之后,直接调用eat便可以完成log的调用。
如果eat有参数,那么可以将eat的参数丢给wrapper。来达到传参的目的。但是这样有一定的弊端,wrapper必须与eat的参数数量一致,同时修改。
1 def log(func): 2 def wrapper(*params): 3 print("...") 4 func(*params) 5 print("...") 6 return wrapper
通过定义的时候收集参数打包到元组中,然后调用时用星号进行解包,这样无论eat有多少参数都可以一并接取。
在此延伸一下,*a,可以传入除了dict之外的任何未命名参数,**a除此之外还可以传入字典参数。
除此之外,一个函数可以加不同的装饰器。
一些常见接口:
Pickle
通过pickle可以将任何纯python对象存储待一个文件中,并在稍后将其取回,这叫做持久的存储对象。
import pickle shoplistfile = 'shoplist.data' shoplist = ['apple','mango','carrot'] f = open(shoplistfile,'wb') pickle.dump(shoplist,f) f.close() del shoplist f = open(shoplistfile, 'rb') storedlist = pickle.load(f) print(storedlist)
要将一个对象存储到一个文件中,我们首先需要通过open以写入二进制模式打开文件,然后调用pickle模块的dump函数,这一过程称作封装。
之后,我们通过pickle模块的load函数接收返回的对象,这个过程称作拆封。
可以将任何数据对象变为二进制形式,并且可恢复。
1 import pickle 2 3 #pickling 4 my_list = [123,3.14] 5 pickle_file=open('E\\my_list.pkl','wb') 6 pickle.dump(my_list,pickle_file) 7 pickle_file.close() 8 9 #unpickling 10 pickle_file=open('E\\my_list.pkl','rb') 11 my_list=pickle.load(pickle_file)
抛出异常
class ShortInputException(Exception): def __init__(self,length,atleast): Exception.__init__(self) self.length=length self.atleast=atleast try: test=input('Enter sth -->') if len(text)<3: raise ShprtInputException(len(text),3) except EOFError: print('Why did you an EOF on me?') except ShortInputException ax ex: print(('ShortInputException: The input was'+'{0} long,excepted an least {1}').format(ex.length ,ex.atleast)) else: print('No exception was raised.')
其中需要参考注意的地方:如何创建新的异常?如何抛出异常?如何调用异常的属性。
assert
mylist=['item'] assert len(mylist)>=1 mylist.pop() assert len(mylist)>=1
with语句
with open('poem.txt') as f: for line in f: print(line,end='')
with语句所使用的的协议会获取由open返回的对象,即thfile,它总会在代码块开始之前调用thefile.__enter__函数,并总会在代码块执行完毕之后调用thefile.__exit__
sys
sys包括了一些特定系统的功能,包括sys.argv以及系统版本,python版本等特性。
assert语句
当assert语句后面的内容是假时,终止程序报出异常(AssertionError)。
1 ls=[1,2]
2 assert len(ls)>1
3 ls.pop()
4 assert len(ls)>1
raise语句
raise [Exception[,args[,traceback]]]
Exception是异常类型,可以使标准异常中的任何一种,也可以是自己设定的,args是自己提供的异常参数,最后一个参数为跟踪异常对象,一般很少用。
raise Exception("wrong")
异常可以有参数,在抛出时会说明自己写入的错误原因。
编写Exception的常用模板:
class CustomError(Exception):
def __init__(self,ErrorInfo):
super().__init__(self)
self.errorinfo=ErrorInfo
def __str__(self):
return self.errorinfo
这样就可以使用自己编写的异常去完成这个抛出异常的操作。
异常种类
IndexError(索引超出),AttributeError(尝试访问未知的对象属性),KeyError(字典中查找一个不存在的关键字),NameError(尝试访问一个不存在的变量)
OSError(操作系统产生异常,例:打开不存在的文件),SyntaxError(Python语法错误),ZeroDivisionError(除数为零)
捕获异常
try-except语句
try:
检测范围
except Exceptiom[as reason]:
出现异常后的处理代码
try:
f=open('1.txt')
print(f.read())
f.close()
except OSError:
print('wrong')
针对不同的异常可以设置多个except,同时如果想了解具体异常情况,可以进行reason的输出。
except OSError as reason:
print("wrong:"+str(reason))
对多个异常也可以进行统一处理,捕获所有异常
````#捕获多个异常
except OSError as reason:
print(''+str(reason))
except TypeError as reason:
print(''+str(reason))
````#捕获所有异常
except:
print("error")
````
try-finally语句
finally是用来收拾残局的,比如在打开文件后,因为其他的语句出现错误,而导致文件不能正常关闭,那么可能导致文件内容丢失,所以我们需要finally收拾残局。
try:
f=open("1.txt")
print("success")
sum=1+'1'
f.close()
except:
print("error")
finally:
f.close()
else可以跟在while,try,for后面,但是如果break或者出现异常,else将不会执行。
使用with语句打开文件不会出现忘记关闭的情况。
try:
with open("1.txt"):
for each_line in f:
print(each_line)
except OSError as reason:
print("error")
特殊方法
特殊方法用来模拟内置类型的某些行为。
__init__(self,....)
在新创建的对象被返回准备使用时被调用
__str__(self)
当使用print函数,或str()时会被调用
__len__(self)
当针对序列对象使用内置len()函数时会被调用
__getitem__(self,key)
使用x[key]索引操作时会被调用
文件系统操作:
OS模块
getcwd() 获取当前应用程序的工作目录
chdir(path) 改变当前的工作目录
listdir(p=‘.’) 列举当前目录下的文件和子文件
mkedir(p) 创建文件夹,若存在抛出异常
makedirs(p) 用于创建多级目录
remove 用于删除指定文件
rmdir(p) 用于删除指定目录
removedirs(p) 用于删除多层目录
rename(old,new) 重命名
system(command) 用来与系统交互
walk(top) 遍历top参数指定路径下的所有子目录,并将结果返回一个三元组(路径,包含目录,包含文件)
OS.path模块
basename(path) 去掉目录路径,单独返回文件名
dirname(path) 去掉文件名,单独返回目录路径
join(path1,path2,,,,,) 将path1,2各部分组合成一个路径名
split(path) 分割文件名与路径,返回(f_path,f_name)元组,如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在
splitext(path) 分离文件名与扩展名,返回(f_name,f_extension)元组
getsize(file) 返回指定文件的尺寸,单位是字节
getatime(file) 返回指定文件最近的访问时间(浮点数秒数,可用time的gmtime()与localtime()函数换算)
getctime(file) 返回指定文件的创建时间(同上)
getmtime(file) 返回文件最新修改的时间
exists(path) 指定路径是否存在 isabs(p) 指定路径是否为绝对路径 isdir(path) 指定路径是否存在且是一个目录 isfile(path) 指定路径是否存在且是一个文件
islink(path) 指定路径是否存在且是一个符号链接 ismount(path) 指定路径是否存在且是一个挂载点 samefile(path1,path2) path1,path2是否指向同一个文件
排列组合模块itertools
另外补充,排列有序,组合无序
排列:itertools.permutations()
import itertools for i in itertools.permutations('BCD', 2): print(''.join(i),end=",") # 输出 BC BD CB CD DB DC print('\n')
组合:itertools.combinations()
import itertools for i in itertools.combinations('BCDEF', 2): print(''.join(i),end=" ") # 输出 BC BD BE BF CD CE CF DE DF EF print('\n')
组合包含自身重复:itertools.combinations_with_replacement()
import itertools for i in itertools.combinations_with_replacement('ABC', 3): print (''.join(i),end=' ') # 输出 AAA AAB AAC ABB ABC ACC BBB BBC BCC CCC print('\n')
eval()
eval
(expression, globals=None, locals=None)
expression必须为一个字符串
eval可以用来执行任意的代码对象,在如此情况下,expression参数是一个代码对象而不是一个字符串,如果代码对象已经被exec编译为模式参数,则eval返回值为none
global和local的意义:
a=10 b=20 c=30 g={'a':6,'b':8} t={'b':100,'c':10} print(eval('a+b+c',g,t))
输出值为116
a=10 b=20 c=30 g={'a':6,'b':8} t={'b':100,'c':10} print(eval('a+b+c',t,g))
输出值为24
另外,eval可以解析json,转化为python可以正常打印的格式
enumerate()
enumerate(sequence, [start=0])
枚举
>>>seasons = ['Spring', 'Summer', 'Fall', 'Winter'] >>> list(enumerate(seasons)) [(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')] >>> list(enumerate(seasons, start=1)) # 下标从 1 开始 [(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]
for循环遍历
>>>seq = ['one', 'two', 'three'] >>> for i, element in enumerate(seq): ... print i, element ... 0 one 1 two 2 three
random()
import random
整数用函数
random.randrange(start,stop[,step])
返回一个随机选择的元素,相当于choice(range(start,stop,step)),实际上并没有构建一个range对象
random.randomint(a,b)
返回随机整数N满足a<=N<=b,相当于randrange(a,b+1)
序列用函数
random.choice(seq)
从非空序列seq返回一个随机元素,如果seq为空,则引发IndexError
random.choices(popilation,weights=None,*,cum_weights=None,k=1)
从population中选择替换,返回大小为k的元素列表,如果population为空,则引发InderError
如果指定了weight序列,则根据相对权重进行选择,或者,如果给出cum_weights序列,则根据累积权重(可能使用itertools.accumulate()计算)进行选择,例如,相对权重[10,5,30,5]相当于累积权重[10,15,45,50],在内部,相对权重在进行选择之前会转化为累积权重,因此提供累积权重可以节省工作量。
如果既未指定weight也未指定cum_weights,则以相等的概率进行U型安泽,如果提供了权重序列,则它必须与population序列的长度相同,不然引发typeerror
weights或cum_weights可以使用任何与random()返回的float值互操作的数值类型(包括整数,浮点数和分数但不包括十进制小数)
对于给定的种子,具有相等加权的choices()函数通常产生与重复调用choice()不同的序列,choices()使用的算法使用浮点运算来实现内部一致性和速度。
choice()使用的算法默认为重复选择的整数运算,以避免因舍入误差引起的小偏差。
random.shuffle(iterable)
返回值为空,此函数的功能是将iterable的顺序打乱,是直接对原iterable进行操作,在原程序不希望这样的情况下,可使用sample进行处理。
random.sample(population,k)
返回从总体序列或集合中选择的唯一元素的k长度的列表。用于无重复的随机抽样。
返回包含来自总体的元素的新列表,同时保持原始总体不变。
实值分布
random.random()
返回[0.0,1.0)范围内的下一个随机浮点数。
random.uniform(a,b)
返回一个随机浮点数N,取决于等式a+(b-a)*random()中的浮点舍入,重点b可以包括或不包括在该范围内。
random.triangular(low,high,mode)
方法返回两个指定数字(包括两者)之间的随机浮点数,但是也可以指定第三个参数,即mode 参数。mode参数使您有机会权衡可能的结果,使其更接近其他两个参数值之一。mode参数默认为其他两个参数值之间的中点,它将不会权衡任何方向的可能结果。
low默认为0,high默认为1,mode默认为low与high的中点
random.betavariate(alpha,beta)------------------beta分布
random.expovariate(lambd)------------------------指数分布
random.gammavariate(alpha,beta)---------------Gamma分布
random.gauss(mu,sigma)----------------------------高斯分布
random.lognormvariate(mu,sigma)----------------对数正态分布
random.vonmisesvariate(mu,kappa)---------------冯·米塞斯分布
random.paretovariate(alpha)--------------------------帕累托分布
random.weibullvariate(alpha,beta)------------------威布尔分布