##函数
def 函数名(参数列表):
方法体
return 返回值
Python函数可以返回多个值。
def hello():
print ("你好,Python!")
hello() //函数调用
函数可以有参数,也可没有参数。可以有返回值return ,也可没有返回值。
函数的调用通过函数名。
参数传递:
def mult_test(a,b,c):
return a*b*c
mult_test(2,c=5,b=3) //正确
mult_test(c=5,b=3,2) //错误,2应放在前面,无默认值的放前面
mult_test(2,3,5) //错误 ,Python没有位置映射
mult_test(*(2,3,5)) //拆解序列函数
可变数量参数传递:
如果参数名前加上一个星号 * ,则表示该参数就是一个可变长参数,可看作元组。
如果参数名前加上两个星号 ** ,则可看作字典。
def cube(name,**naturn):
all_naturn = { 'x':1,'y':1,'z':1,'color':'while','weight':1}
all_naturn.update(naturn)
print(name,"立方体的属性:")
print('体积:'all_naturn['x'] * all_naturn['y'] * all_naturn['z'])
print('颜色:'all_naturn[ 'color'])
print('重量:,all_naturn[ 'weight'])
cube('first')
cube('second',y=3,color='red')
cube('third',z=2,color='green',weight=10)
拆解序列的函数调用
- 拆解元组
- 拆解字典
def mysum(a,b):
return a+b
print('拆解元组调用:')
print(mysum(*(3,4)))
print('拆解字典调用:')
print(mysum(**('a':3,'b':4)))
函数调用时参数的传递异常:
函数上一次的调用结果很可能会叠加在下一次的调用
def myfun(lst=[]):
lst.append('abc')
print(lst)
myfun() #['abc']
myfun() #['abc','abc']
myfun() #['abc','abc','abc']
匿名函数
lambda 参数列表:方法体
import math
s = lambda x1,y1,x2,y2:math.sqrt((x1-x2)**2+(y1-y2)**2)
s(1,1,0,0)
类:
类:
每个类都有属性即变量,和方法。
每个类都有一个构造函数,其函数名与类名相同。构造函数是在创建类的对象后自动执行,通常用于初始化数据。
方法的调用:类的方法通过类的对象调用:对象.方法名
def coord_chng(x,y):
return (abs(x),abs(y))
class Ant:
def __init__(self,x=0,y=0):
self.x = x;
self.y = y;
self.disp_point()
def move(self,x,y):
x,y = coord_chng(x,y)
self.edit_point(x,y)
self.disp_point()
def edit_point(self,x,y):
self.x +=x
self.y += y
def disp_point(self):
print("当前位置:(%的,%d)" % (self.x,self.y))
ant_a = Ant()
ant_a.move(2,4)
ant_a.move(-9,6)
继承
class PrntA:
namea = 'prntA'
def set_value(self,a):
self.a =a;
def set_namea(self,namea):
PrntA.namea=namea
def info(self)
print('PrntA:%s,%s' % (PrntA.namea,self.a))
class PrntB:
nameb = 'PrntB'
def set_nameb(self,nameb):
PrntA.nameb = nameb
def info(self):
print('PrntB:%s' %(PrntB.nameb,))
class Sub(PrntA,PrntB): //多继承
pass
异常处理
-
自动检测异常
-
手工抛出异常(人为激发异常)
-
自定义异常
try:
<语句块>
except 异常名1:
语句块
except 异常名2:
语句块
else:
语句块 #未触发异常,则执行该语句
finally:
语句块
def testTryAll(index,i):
stulst = ["John","Jenny","Tom"]
try:
print(len(stulst[index])/i)
except:
print("Error!")
testTryAll(1,0) #发生除零异常
手工抛出异常raise
raise 异常名
raise 异常名,附加数据
raise 类名
def testRaise():
for i in range(5):
try:
if i == 2:
raise NameError
except NameError:
print('Raise a NameError')
print(i)
print('End...')
testRaise()
assert语句
assert语句是简化的raise语句,它引发异常的前提是其后面的条件测试为假
def testAssert():
for i in range(3):
try:
assert i<2
except AssertionError:
print('Raise a AssertionError!')
print('End....')
testAssert()
自定义异常类
class RangeError(Exception) : #继承异常类
def __init__(self,value):
self.value = value
def __str__(self):
return self.value
raise RangeError('Range Error!')
用pdb调试程序
调试语句块:run(’’’ ‘’’)函数
import pdb
pdb.run('''
for i in range(3):
print(i)
''')
调试函数:
import pdb
def sum(maxint):
s = 0
for i in range(maxint):
s += i
return s
pdb.runcall(sum,10)
用testmod函数测试 :写入程序中单元测试
import pdb
def grade(sum):
"""
>>>grade(100)
'优秀'
>>>grade(80)
'良'
>>>grade(65)
'合格'
>>>grade(10)
'不合格'
"""
if sum >90:
return '优秀'
if sum > 80:
return '良'
if sum >60:
return '合格'
if sum <60:
return '不合格'
if name == '__main__':
import doctest
doctest.testmod()
用testfile函数测试:不想写进程序中进行单元测试
def grade(sum):
if sum >90:
return '优秀'
if sum > 80:
return '良'
if sum >60:
return '合格'
if sum <60:
return '不合格'
也可用命令行python:
python -m doctest 7-14.py
from test import grade #将上面程序文件存入test.py文件中
>>>grade(100)
'优秀'
>>>grade(80)
'良'
>>>grade(65
'合格'
>>>grade(10)
'不合格'
也可以用命令行:
python -m dictest mytest.txt
模块调用
就是调用a.py文件
import a
模块位置
import sys #导入sys模块
print(sys.path) #输出当前模块查找路径(列表形式)
sys.path.append(Apath) #添加Apath为模块查找路径
编译
对于不作为模块的程序,Python不会再运行脚本后将其编译成字节码的形式。如果将其编译,可以使用complie模块
#file: complie
import py_complie;
py_commplie.complie(’ a8_2.py’,‘a8_2.pyc’);
另外可以通过python的命令行选项将脚本优化编译。
- -O 该选项对脚本的优化不多,编译后的脚本以“ .pyo”为扩展名。凡是为扩展名的Python字节码都是经过优化的
-OO 该选项对脚本优化的程度角度。使用该标志可以使得编译的Python脚本更小。使用该选项可以导致脚本运行错误,因此,应谨慎使用
命令行下使用方法:
python -O complie.py
python -OO complie.py
具有独立运行能力的模块:
name = 'module_test' #测试这个模块
def m_t_pr():
print('模块module_test中m_t_pr函数')
if __name__ == '__main__': #测试专用,与main方法类似。不加就是交互式
p_t_pr()
print(name)
包:
包就是一个目录,可以装多个py文件,init.py是一个空文件,是包的一个标志
迭代器
迭代器主要有两种:
iter():该方法返回对象本身,他是for语句使用迭代器的要求
next():该方法用于返回容器中一个元素或数据。当容器中的数据佣金是,应该引发StopIteration异常
自定义异常
class MyIterator:
def __init__(self,x=2,xmax=100):
self.__mul,self.x = x,x
self.__xmax = xmax
def __iter__(self): #定义迭代器协议方法,返回类自身
return self
def __next__(self): #自定义异常
if self.__x and self.__x !=1:
self.__mul *= self._x
if self.__mul <= self.__xmax:
return self.mul
else:
raise StopIteratoin
else:
raise StopIteration
if __name__ == '__main__':
myiter = MyIterator()
for i in myiter:
print('迭代的数据元素为:'i)
内建迭代器函数iter()
class Counter:
def __init__(self,x=0):
self.x= x
counter = Counter() #实例化Counter
def used_iter():
conter.x +=2
return counter.x
for i in iter(use_iter,8):
print('本次遍历的数值: ',i)
itertools模块中常用工具函数
有三类:
无限迭代器:
count(start,[step]) #从start开始,异step为步长进行计数迭代
cycle(seq) #无限循环迭代seq
repeat(elem.[n]) #循环迭代elem
迭代短序列
chain(p,q,…)
compress(data,selectors) #连接迭代(将p 和q连接起来迭代)
dropwhile(pred,seq) #当predict对序列元素处理结果为假时开始迭代seq后所有值
filterfalse(pred,seq) #当pred处理为假的元素
takewhile(pred,seq) #与dropwhile相反
tee(it,n)
zip_longest(p,q,…)
组合迭代
product(p,q,…[,n]) #迭代排列出所有的排列
permutations(p,r) #迭代序列中r个元素的排列
combinations(p,r) #迭代序列中r个元素的组合
import itertools
for i in itertools.count(1,3):
print(i)
if i >=10:
break
//cycle
x =0
for i in itertools.cycle(['a','b']):
print(i)
x += 1
if x >=6:
break
//repeat
list(itetools.repeat(3,3))
list(itertools.chain([1,3],[2,3]))
list(itertools.compress([1,2,3,4],[1,[],True,3]))
list(itertools.dropwhile(lambda x:x>6,[8,9,1,2,8,9]))
list(itertools.takewhile(lambda x:x>10,[18,19,1,21,8,9]))
for its in itertools.tee([0,1],2):
for it in its:
print(it)
list(itertools.permutations('abc',2))
list(itertools.combinations('abc',2))
生成器
生成器对象是使用yield关键字定义的函数对象,因此,生成器也是一个函数。生成器用于生成一个值的徐磊,以便在迭代中使用
def myYield(n): #定义一个生成器
while n>0:
print("开始生成。。。:")
yield n #yield语句,用于返回给调用者其后表达式的值
print ("完成一次...:")
n -= 1
if __name__ == '__main__':
for i in myYield (4): #for语句遍历生成器
print("遍历得到的值: ",i)
print()
my_yield = myYield(3) #生成一个生成对象
print('已经实例化生成器对象')
my_yield.__next__() #手工调用器特殊方法,获取序列中一个值
print('第一次调用__next__()方法: ')
my_yield.__next__()
深入生成器
演示一个可以接受调用者传来的值并重新初始化生成器生成的值
def myYield(n):
while n>0:
rcv = yield n #rcv用来接受调用者传来的值
n -= 1
if rcv is not None:
n = rcv
if __name__ == '__main__':
my_yeild = myYield(3)
print(my_yield.__next__())
print(my_yield.__next__())
print('传给生成器一个值,重新初始化生成器。')
print(my_yield.send(10))
print('my_yield.__next__())
生成器与协程
send()方法来重置生成器的生成序列,其实也被称为协程。协程是一种解决程序并发的方法
def consumer():
print('等待接受处理任务。。。')
while True:
data = (yield)
print('收到任务:',data)
def producer():
c = consumer()
c.__next__()
for i in range(3):
print('发送一个任务。。。','任务%d' %i)
c.send('任务%d' % i)
if __name__ == '__main__':
producer()
装饰器
装饰器是一种增加函数或类功能的简单方法,他可以快速地给不同的函数或类插入相同 的功能。从本质上说,它是一种代码实现方式
def abc(fun):
def wrapper(*args,**kwargs):
print('开始运行...')
fun(*args,**kwargs)
print('开始结束!')
return wrapper
@abc
def demo_decoration(x):
a = [ ]
for i in range(x):
a.append(i)
print(a)
@abc
def hello(name):
print('Hello ',name)
if __name__ == '__main__':
demo_decoration(5)
print()
hello('John')
闭包
x = 14
def foo():
x =3
def bar():
print('x is %d' % x)
bar() #闭包特征
if __name__ == '__main__':
foo()
**闭包与延迟求值
闭包可以实现先将参数传递给一个函数,而不是立即运行,已达到延迟求值的目的
def delay_fun(x,y):
def caculator():
return x + y
return calulator #闭包延时
if __name__ == '__main__':
print('返回一个求和的函数,并不求和。')
msum = delay_fun(3,4)
print()
print('调用并求和: ')
print(msum())
闭包与泛型函数
def line(a,b):
def aline(x):
return a*x + b
return aline
if __name__ == '__main__':
line23 = line(2,3) //返回的是函数
line(50 = line(5,0)
print(line(4))
print(line(2))
上下文管理器
上下文管理器是指实现上下文管理协议方法的对象,他主要用于安全地释放资源(如打开的文件、数据库连接或网络连接、对对象的锁定等)。
enter(self):方法是进入上下文时调用的,它创建并返回一个可以引用的资源对象,供with语句块使用
exit(self,type,value,tb):方法是退出上下文是调用的,它主要用来安全地释放资源对象。方法中的参数type,value,tb用于跟踪退出错误时发生的错误类型、值和跟踪信息
格式:
with contest as var:
pass
class FileMgr:
def __init__(self,filename):
self.filename = filename
self.f = None
def __enter__(self):
self.f = open(self.filename,encoding='utf-8')
return self.f
def __exit__(self,t,v,tb):
if self.f:
self.f.colse()
if __name__ =='__main__':
with FileMgr('a10_4.py') as f:
for line in f.readlines():
print(line,end=' ')
#通过装饰器contextmanager实现的一个上下文管理器,
import contextlib
@contextlib.contextmanager
def my_mgr(s,e):
print(s)
yield s +' ' +e
print(e)
if __name__ =='__main__':
with my_mgr('start','end') as val:
print(val)
hasattr()和setattr()
hasattr()可以某个对象具有某个属性
setattr()修改对象属性的实例
class DemoClass:
class _val = 3;
def __init__(self,x=0,y=0):
self.x = x
self.y = y
self.info()
def info(self):
print('类属性class_val:',DemoClass.class_val)
print('实例属性x: ',self.x)
print('实例属性y: ',self.y)
if __name__ == '__main__':
dc = DemoCLass()
if hasattr(DemoClass,'class_val'):
setattr(DemoClass,'class_val',1000)
if hasattr(dc,'x'):
setattr(dc,'x','xxxxx')
if(hasattr(dc,'y'):
setattr(dc,'y','yyyy')
dc.info()
setattr(dc,'z','zzzz')
print('添加属性z', dc.z)
重载类的特殊方法
方法名 | 描 述 |
---|---|
__init __ | 构造函数,生成对象时调用 |
__ del__ | 析构函数,释放对象时调用 |
__ add__ | 加运算 |
__ mul__ | 乘运算 |
__cmp __ | 比较运算 |
__repr __ | 打印,转换 |
__setitem __ | 按照索引赋值 |
__getitem __ | 按照索引获取值 |
__len __ | 获得长度 |
__call __ | 函数调用 |
class Book:
def __init__(self,name='Python 从入门到精通'):
self.name = name
def __add__(add,obj):
return self.name + ' add ' + obj.name
def __len__(self):
return len(self.name)
if __name__ == '__main__':
booka = Book()
bookb = Book('Java 从入门到精通')
print("len(booka):",len(booka))
print("len(bookb: ",len(bookb))
print(booka + bookb)