Python函数

##函数

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值