设为首页 收藏本站
查看: 1065|回复: 0

[经验分享] Python学习笔记《Python核心编程》第11章 函数和函数式编程

[复制链接]

尚未签到

发表于 2015-4-23 07:58:15 | 显示全部楼层 |阅读模式
  如果函数没有返回值。则函数的返回值为None。函数可以返回一个值或者对象。
       def foo():
             return ['xyz',1000000,-98.6]
       def bar():
             return 'abc',[12,'python'],'Guido'      #其实返回的是一个元组。省略了圆括号('abc',[12,'python'],'Guido')
  用圆括号来调用函数。如:bar()     foo()
  关键字参数:允许参数缺失或者不按顺序,解释器能通过给出的关键字来匹配参数的值。如:
  def foo(x,y):
  '文档字符串'
  foo_suite   
  标准调用函数foo: foo(1,2)  foo("bar","foo")   # 按照顺序输入参数
  关键字调用foo:foo(x=1,y=2)or foo(y=2,x=1)         foo(y="foo",x="bar")   #按照关键字赋值参数,可以不按顺序
  函数示例:



#!/usr/bin/env python
from operator import add, sub
from random import randint, choice
ops = {'+':add,'-':sub}           # 全局字典
MAXTRIES = 2                      # 全局尝试次数
def doprob():                     #定义函数doprob
op = choice("+-")             #random.choice()函数随机返回序列中的一个元素
nums = [randint(1,10) for i in range(2)]  #[randint(1,10),randint(1,10)]
nums.sort(reverse = True)     
ans = ops[op](*nums)
pr = '%d %s %d =' % (nums[0],op,nums[1])
oops = 0
while True:
try:
if int(raw_input(pr)) == ans:
print 'correct'
break
if oops == MAXTRIES:
print 'answer\n%s%d' % (pr,ans)
else:
print 'incorrect...try again'
oops += 1
except (KeyboardInterrupt,\
EOFError,ValueError):
print 'invalid input ...try agin'
def main():
while True:
doprob()
try:
opt = raw_input('Again? [y]').lower()
if opt and opt[0] == 'n':
break
except(KeyboardInterrupt,EOFError):
break
if __name__ == '__main__':
main()
  注:Python 不允许在函数未申明之前,对其进行引用或者调用。
  内部/内嵌函数:
  在函数体内创建另外一个函数式完全可以的,这种函数叫做内部/内嵌函数。    ————内部函数作用域只在外部函数作用域内,外部访问不了。   
  函数装饰器 ——装饰器就是函数,装饰器仅仅用来“装饰”函数的包装,返回一个修改后的函数对象,将其重新赋值原来的标识符,并永久失去对原始函数对象的访问。
  装饰器的语法以@开头,接着是装饰器函数的名字和可选的参数。紧跟着装饰器声明的是被修饰的函数和装饰函数的可选参数。如下:
  @decorator(dec_opt_args)
  def func2bdecorated(func_opt_args):
  :
  示例:



#!usr/bin/env python
from time import ctime,sleep
def tsfunc(func):
def wrappedFunc():
print '[%s] %s() called' % (ctime(),func.__name__)   # 时间戳调用
return func()   #目标函数调用
return wrappedFunc
@tsfunc
def foo():
pass
foo()
sleep(4)
for i in range(2):
sleep(1)
foo()
  输出:
  [Sat Jan 26 20:39:47 2013] foo() called
[Sat Jan 26 20:39:52 2013] foo() called
[Sat Jan 26 20:39:53 2013] foo() called
  传递函数——与JS类似,python中的函数 也可以作为参数传递,并在函数体内调用这些函数。   



#!/usr/bin/env python
# 传递和调用函数
def convert(func,seq):
'conv.sequence of nubers to same type'
return [func(eachNum) for eachNum in seq]
myseq = (123,45.67,-6.2e8,9999999L)
print convert(int,myseq)   # 传递int函数
print convert(long,myseq)  # 传递long函数
print convert(float,myseq) # 传递float函数
  输出为:
  [123, 45, -620000000, 9999999]
[123L, 45L, -620000000L, 9999999L]
[123.0, 45.67, -620000000.0, 9999999.0]
  函数的默认参数:python中用默认值声明变量的语法是所有的位置参数必须出现在任何一个默认参数之前。

       def func(posargs,defarg1=dva11,defarg2=dva2,...):
             pass
  抓取web页面示例代码:



#!/usr/bin/env python
from urllib import urlretrieve
def firstNonBlank(lines):
for eachLine in lines:
if not eachLine.strip():
continue
else:
return eachLine
def firstLast(webpage):
f = open(webpage)
lines = f.readlines()
f.close()
print firstNonBlank(lines),   # 输出文件非空白的第一行
print '\n-----------------\n'
lines.reverse()               # 翻转lines
print firstNonBlank(lines),   # 输出第一行也就是倒数一行
def download(url = 'http://www.baidu.com',process = firstLast):
try:
retval = urlretrieve(url)[0]     # 下载代码到文件 'c:\\users\\admini~1\\appdata\\local\\temp\\tmp7msit8'
except IOError:
retval = None
if retval:
process(retval)
if __name__ == '__main__':
download()
  返回值:



百度一下,你就知道      html,body{height:100%;}html{overflow-y:auto}#wrapper{position:relative;_position:;min-height:100%}#content{padding-bottom:100px;text-align:center;}#ftCon{height:100px;position:absolute;bottom:44px;text-align:center;width:100%;margin:0 auto;z-index:0;overflow:hidden;}#ftConw{width:720px;margin:0 auto;}body{font:12px arial;text-align:;background:#fff}body,p,form,ul,li{margin:0;padding:0;list-style:none}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{color:#999;padding:4px 10px 5px 0;text-align:right}#u a{margin:0 5px}#u .reg{margin:0}#m{width:720px;margin:0 auto;}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:110px;text-align:left;z-index:1;}input{border:0;padding:0}#nv{height:19px;font-size:16px;margin:0 0 4px;text-align:left;text-indent:137px;}.s_ipt_wr{width:418px;height:30px;display:inline-block;margin-right:5px;background:url(http://s1.bdstatic.com/r/www/img/i-1.0.0.png) no-repeat -304px 0;border:1px solid #b6b6b6;border-color:#9a9a9a #cdcdcd #cdcdcd #9a9a9a;vertical-align:top}.s_ipt{width:405px;height:22px;font:16px/22px arial;margin:5px 0 0 7px;background:#fff;outline:none;-webkit-appearance:none}.s_btn{width:95px;height:32px;padding-top:2px\9;font-size:14px;background:#ddd url(http://s1.bdstatic.com/r/www/img/i-1.0.0.png);cursor:pointer}.s_btn_h{background-position:-100px 0}.s_btn_wr{width:97px;height:34px;display:inline-block;background:url(http://s1.bdstatic.com/r/www/img/i-1.0.0.png) no-repeat -202px 0;*position:relative;z-index:0;vertical-align:top}#lg img{vertical-align:top;margin-bottom:3px}#lk{margin:33px 0}#lk span{font:14px "宋体"}#lm{height:60px}#lh{margin:16px 0 5px;word-spacing:3px}.tools{position:absolute;top:-4px;*top:10px;right:7px;}#mHolder{width:62px;position:relative;z-index:296;display:none}#mCon{height:18px;line-height:18px;position:absolute;cursor:pointer;padding:0 18px 0 0;background:url(http://s1.bdstatic.com/r/www/img/bg-1.0.0.gif) no-repeat right -134px;background-position:right -136px\9}#mCon span{color:#00c;cursor:default;display:block}#mCon .hw{text-decoration:underline;cursor:pointer}#mMenu a{width:100%;height:100%;display:block;line-height:22px;text-indent:6px;text-decoration:none;filter:none\9}#mMenu,#user ul{box-shadow:1px 1px 2px #ccc;-moz-box-shadow:1px 1px 2px #ccc;-webkit-box-shadow:1px 1px 2px #ccc;filter: progid:DXImageTransform.Microsoft.Shadow(Strength=2, Direction=135, Color="#cccccc")\9;}#mMenu{width:56px;border:1px solid #9b9b9b;list-style:none;position:absolute;right:27px;top:28px;display:none;background:#fff}#mMenu a:hover{background:#ebebeb}#mMenu .ln{height:1px;background:#ebebeb;overflow:hidden;font-size:1px;line-height:1px;margin-top:-1px}#cp,#cp a{color:#666666;}#seth{display:none;behavior:url(#default#homepage)}#setf{display:none;}#sekj{margin-left:14px;}
-----------------

  可变长度的参数:
  非关键字可变长度参数(元组)—— 可变产长度参数元组必须在位置和默认参数之后,带元组的函数普遍语法如下:
  def function_name([formal_args,] *vargs_tuple):
              "function_doc"
              function_body_suite
   星号操作符之后的形参将作为元组传递给函数,元组保存了所有传递给函数的额外的参数(匹配了所有位置和具名参数后剩余的)。
   如果没有给出额外的参数,元组为空。示例:



>>> def tupleVarARGS(arg1,arg2='defaultB',*theRest):
'display regular args and non-keyword variable args'
print 'rotmal arg1:',arg1
print 'formal arg 2:',arg2
for eachXtrArg in theRest:
print 'another arg:',eachXtrArg

>>> tupleVarARGS('ABC')
rotmal arg1: ABC
formal arg 2: defaultB
>>> tupleVarARGS('ABC','EFG')
rotmal arg1: ABC
formal arg 2: EFG
>>> tupleVarARGS('ABC','EFG',123,456,78,88)
rotmal arg1: ABC
formal arg 2: EFG
another arg: 123
another arg: 456
another arg: 78
another arg: 88
>>>
  关键字变量参数(字典)语法如下:
  def function_name ([formal_args,][*vargst,] **vargsd):
  function_doc
  functnion_body_suite
  关键字变量参数应该为函数定义的最后一个参数,带**,示例:        



def dictVarArgs(arg1,arg2='defaultB',**theRest):
'display w regular args and keyword variable args'
print 'formal arg1:',arg1
print 'formal arg2:',arg2
for eachXtrArg in theRest.keys():
print 'xtra arg %s:%s' % \
(eachXtrArg,str(theRest[eachXtrArg]))
  输出:



>>> dictVarArgs(1220,740.0,c='grail')
formal arg1: 1220
formal arg2: 740.0
xtra arg c:grail
>>> dictVarArgs(arg2='vvg',c=123,d='vvg2',arg1='asdfasd')
formal arg1: asdfasd
formal arg2: vvg
xtra arg c:123
xtra arg d:vvg2
>>> dictVarArgs('one',d=10,e='zoo',men = ('freud','gaudi'))
formal arg1: one
formal arg2: defaultB
xtra arg men:('freud', 'gaudi')
xtra arg e:zoo
xtra arg d:10
  关键字和非关键字可变长参数都有可能在同一函数中,只要关键字字典是最后一个参数并且非关键字元组先与它之前出现.



def newfoo(arg1,arg2,*nkw,**kw):
'doc'
print 'arg1 is:',arg1
print 'arg2 is:',arg2
for eachNKW in nkw:
print 'non-keword arg:',eachNKW
for eachKW in kw.keys():
print 'kew word arg "%s": %s' % \
(eachKW,kw[eachKW])


输出:
>>> newfoo('wolf',3,'projiects',freud=90,gamble=96)
arg1 is: wolf
arg2 is: 3
non-keword arg: projiects
kew word arg "gamble": 96
kew word arg "freud": 90
  函数式编程举例:      



#!usr/bin/env python
def testit(func,*nkwargs,**kwargs):
try:
retval = func(*nkwargs,**kwargs)
result = (True,retval)
except Exception,diag:
result = (False,str(diag))
return result
def test():
funcs = (int,long,float)
vals = (123,12.34,'1234','12.34')
for eachFunc in funcs:
print '_'*20
for eachVal in vals:
retval = testit(eachFunc,eachVal)
if retval[0]:
print '%s(%s) = ' %\
(eachFunc.__name__,eachVal),retval[1]
else:
print '%s(%s) = FAILED:'%\
(eachFunc.__name__,eachVal),retval[1]
if __name__ =='__main__':
test()


输出:
____________________
int(123) =  123
int(12.34) =  12
int(1234) =  1234
int(12.34) = FAILED: invalid literal for int() with base 10: '12.34'
____________________
long(123) =  123
long(12.34) =  12
long(1234) =  1234
long(12.34) = FAILED: invalid literal for long() with base 10: '12.34'
____________________
float(123) =  123.0
float(12.34) =  12.34
float(1234) =  1234.0
float(12.34) =  12.34
  函数式编程:
  匿名函数与lambda----------------------与javascript中的匿名函数类似
  lambda [arg1[, arg2, ... argN]]: exprission
  python 允许用lambda关键字创建匿名函数。一个完整的lambda“语句”代表了以个表达式,这个表达式的定义体必须和声明放在同一行。
  def add(x,y):return x + y    lambda x, y: x + y
  def usuallyAdd2(x,y=2):return x + y    lambda x,y=2 : x + y
  def showAllAsTuple(*z):return z          lambda *z : z
  内建函数apply(),filter(),map(),reduce()
  ----------------------------------------------------------------------------------------------
  内建函数                                                   描述
  apply(func[,nkw][,kw])                                用可选的参数来调用func,nkw为非关键字参数,kw为关键字参数;返回值是函数调用的返回值
  filter(func,seq)                                           调用一个布尔函数func来遍历迭代每一个seq中的元素;返回一个是fanc返回值为ture的元素的序列
  map(func,seq1[,seq2...])                            将函数func作用于给定序列s的每个元素,并用以个列表来提供返回值;如果fanc为None,func表现为一个身份函                                     数,返回一个含有每个序列中元素集合的N个原始的列表
  reduce(func,seq[,init])                                将二元函数作用与seq序列的元素,每次携带一堆,连续地将现有的结果和下一个值作用在获得的随后的结果上,最后减少我们的序列为一个单一的返回值;如果初始值init给定,第一个比较会是init和第一个序列元素而不是序列的头两个元素。
  
  apply()-------已经被淘汰掉.....
  filter() -------为已知的序列的每个元素调用给定布尔函数。每个filter返回的非零(true)值元素添加到一个列表中,返回的对象是以个从原始队列中“过滤后”的队列。
  示例:过滤掉偶数返回奇数列表:



#!/usr/bin/env python
from random import randint
def odd(n):
return n % 2
allNums = []
for eachNum in range(10):  # 只是为了循环10次
allNums.append(randint(1,99))   # 每次添加一位随机数
print filter(odd,allNums) # 过滤
  上面示例中的add()函数可以用一个lambda表达式替换:



from random import randint
allNums = []
for eachNum in range(10):
allNums.append(randint(1,99))
print filter(lambda n: n%2,allNums)
  也可以用列表解析代替如下:



from random import randint as ri
print[n for n in [ri(1,99) for i in range(9)] if n%2]
    map()  --  将函数调用“映射”到每个序列的元素上,并返回含有所有返回值的列表。   



map(lambda x : x+2,[0,1,2,3,4,5,6])    #[2, 3, 4, 5, 6, 7, 8]
map(lambda x : x**2,range(6))          #[0, 1, 4, 9, 16, 25]
[x+2 for x in range(6)]                #[2, 3, 4, 5, 6, 7]
[x**2 for x in range(6)]               #[0, 1, 4, 9, 16, 25]
  map() 使用带多个序列的示例:



map(lambda x,y:x+y,[1,3,5],[2,4,6])         #[3, 7, 11]
map(lambda x,y:(x+y,x-y),[1,3,5],[2,4,6])   #[(3, -1), (7, -1), (11, -1)]
map(None,[1,3,5],[2,4,6])                   #[(1, 2), (3, 4), (5, 6)]   同zip()函数
  reduce()  ----  使用一个二元函数(接受两个参数,返回一个值),一个序列,一个可选的初始化器。将那个列表的内容“减少”为以个单一的值。(它通过取出序列的头两个元素,将他们传入二元行数来获得一个单一的值来实现。然后又用这个值和序列的下一个元素来获得又一个值,然后继续,知道整个序列的内容都遍历完毕以及最后的值会被计算出来为止).......
       reduce(func,[1,2,3]) == func(func(1,3), 3)    #  如果给定了初始化器,则一开始的迭代会用初始化器和易个序列的元素来进行。
     如果用程序来模拟reduce,实际就是这样:



def mySum(x,y):return x + y
allNums = range(5) #[0,1,2,3,4]
total = 0
for eachNum in allNums:
total = mySum(total,eachNum)
print 'the total is:',total    #the total is: 10
  使用lambda 和 reduce(),如下:



print 'the total is:',reduce((lambda x,y:x+y),range(5))
  偏函数应用:   ------ 通过functional模块中partial()函数来创建PFA(偏函数).  



from operator import add,mul
from functools import partial
add1 = partial(add,1)     # add1(x) ==  add(1,x)
mul100 = partial(mul,100) # mul100(x) == mul(100,x)
print add1(10)     #11
print mul100(10)   #100
   变量的作用域:
    global语句:为了明确地引用一个已命名的全局变量,必须使用global语句,语法如下:
  flobal var1[, var2 [, ....varN]]      



def foo():
global is_this_global
this_is_local = 'abc'
is_this_global = 'def'
print this_is_local + is_this_global
foo()    # abcdef
print is_this_global      #def
  闭包:-----与javascript中的闭包相似
  简单示例:



def counter(start_at = 0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
count = counter(5)
print count()  #6
print count()  #7
print count()  #8
print count()  #9
  变量作用域和名称空间



#!/usr/bin/env python
j,k=1,2
def proc1():
j,k = 3,4
print "j==%d and k == %d" % (j,k)
k = 5
def proc2():
j = 6
proc1()   #3,4
print "j==%d and k == %d" % (j,k)
k = 7
proc1()   # 3,4
print "j==%d and k == %d" % (j,k)  #1,7

j = 8
proc2()   #6,7
print "j==%d and k == %d" % (j,k)  #8,7


输出:
j==3 and k == 4
j==1 and k == 7
j==3 and k == 4
j==6 and k == 7
j==8 and k == 7
  递归:函数包含了对其自身的调用,该函数就是递归的。



def factorial(n):
if n==0 or n==1:    # 0! =1! =1
return 1
else:
return (n*factorial(n-1))
>>> factorial(10)     #3628800
  生成器: 从语法上讲,生成器是一个带yield语句的函数。?

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59789-1-1.html 上篇帖子: Python学习笔记(7):数据结构 下篇帖子: Python的getattr(),setattr(),delattr(),hasattr()
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表