python函数局部变量用法实例分析

2024-04-14

python函数局部变量用法实例分析(通用6篇)

篇1:python函数局部变量用法实例分析

作者:东郭先生 字体:[增加 减小] 类型:

当你在函数定义内声明变量的时候,它们与函数外具有相同名称的其他变量没有任何关系,即变量名称对于函数来说是 局部 的。这称为变量的 作用域 。所有变量的作用域是它们被定义的块,从它们的名称被定义的那点开始。

一、使用局部变量

示例如下:

#!/usr/bin/python# Filename: func_local.pydef func(x): print ‘x is‘, x x = 2 print ‘Changed local x to‘, xx = 50func(x)print ‘x is still‘, x

输出:

$ python func_local.pyx is 50Changed local x to 2x is still 50

工作原理:

在函数中,我们第一次使用x的 值 的时候,Python使用函数声明的形参的值。

接下来,我们把值2赋给x。x是函数的局部变量。所以,当我们在函数内改变x的值的时候,在主块中定义的x不受影响。

在最后一个print语句中,我们证明了主块中的x的值确实没有受到影响,

二、使用global语句

如果你想要为一个定义在函数外的变量赋值,那么你就得告诉Python这个变量名不是局部的,而是 全局 的。我们使用global语句完成这一功能。没有global语句,是不可能为定义在函数外的变量赋值的。

你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量)。然而,我并不鼓励你这样做,并且你应该尽量避免这样做,因为这使得程序的读者会不清楚这个变量是在哪里定义的。使用global语句可以清楚地表明变量是在外面的块定义的。

使用global语句示例:

#!/usr/bin/python# Filename: func_global.pydef func: global x print ‘x is‘, x x = 2 print ‘Changed local x to‘, xx = 50func()print ‘Value of x is‘, x

输出:

$ python func_global.pyx is 50Changed global x to 2Value of x is 2

工作原理:

global语句被用来声明x是全局的――因此,当我们在函数内把值赋给x的时候,这个变化也反映在我们在主块中使用x的值的时候。

你可以使用同一个global语句指定多个全局变量。例如global x, y, z。

希望本文所述对大家的Python程序设计有所帮助。

篇2:python函数局部变量用法实例分析

这篇文章主要介绍了python函数形参用法,较为详细的讲述了Python函数形参的功能、定义及使用技巧,需要的朋友可以参考下

本文实例讲述了python函数形参用法,分享给大家供大家参考。具体如下:

函数形参:

函数取得的参数是你提供给函数的值,这样函数就可以利用这些值 做 一些事情。这些参数就像变量一样,只不过它们的值是在我们调用函数的时候定义的,而非在函数本身内赋值。

参数在函数定义的圆括号对内指定,用逗号分割。当我们调用函数的时候,我们以同样的方式提供值。注意我们使用过的术语――函数中的参数名称为 形参 而你提供给函数调用的值称为 实参 。

使用函数形参:

#!/usr/bin/python# Filename: func_param.pydef printMax(a, b): if a > b: print a, ‘is maximum‘ else: print b, ‘is maximum‘printMax(3, 4) # directly give literal valuesx = 5y = 7printMax(x, y) # give variables as arguments

运行结果如下:

4 is maximum

7 is maximum

工作原理:

这里,我们定义了一个称为printMax的函数,这个函数需要两个形参,叫做a和b,

我们使用if..else语句找出两者之中较大的一个数,并且打印较大的那个数。

在第一个printMax使用中,我们直接把数,即实参,提供给函数。在第二个使用中,我们使用变量调用函数。printMax(x, y)使实参x的值赋给形参a,实参y的值赋给形参b。在两次调用中,printMax函数的工作完全相同。

篇3:python函数局部变量用法实例分析

Copulas函数作为新型联合分布函数,已应用到金融、信息、水文等多领域,但在水文多变量研究中,大多是基于copulas函数研究洪水和降雨特性。熊立华等[1]针对同一河流上下游的两水文站点采用Copula连接函数建立与模拟两站点的年最大洪水联合分布函数。Grimaldi和Serinaldi[2]基于三维非对称式Copula函数进行洪水频率分析,并与对称式和标准Gumbel逻辑模型进行了比较研究。张娜等[3,4]以隔河岩水库为例,采用3维非对称Frank Copula函数构建汛期分为三分期,边缘分布为P-III分布的分期洪水联合分布,并在假定的设计洪水值的联合重现期等于防洪标准T的前提下,推导基于Frank Copoula函数的分期设计洪水频率和汛限水位。De Michele和Salvadori[5]用二维Copula函数建立了边缘分布为广义Parato分布的雨强和历时的联合分布。Salvadori和De Michele[6]又基于Copula 函数进一步研究了暴雨统计量的联合分布, 进而推导出暴雨前某固定时段内降雨量和前期土壤湿度的分布函数。Grimaldi和Serinaldi[2]运用三维Copula函数进行设计雨量图的分析。Zhang和Singh[7,8]先后对降雨的雨强、雨深和历时进行两变量和三变量的频率分析,并得出联合重现期。从现有文献来看,多变量干旱特征联合分布特性有待进一步深入研究。本文以渭河流域华阴站降雨资料为例,采用Frank和Gaussian copulas函数分析二维干旱联合特性分布,构建Frank pair-copula、Gaussian copula、M3 copula函数,对比分析三维干旱联合特性。

1 Copulas

本文采用Frank和Gaussian copulas[9]函数分析二维干旱联合特性分布,构建Frank pair-copula[10,11]、Gaussian copula、M3 copula[12,13]三维联合分布函数。

Frank

-1θln[1+(e-θu1-1)(e-θu2-1)e-θ-1](1)

Frank pair-copula

0u2C13/2[C12[u1,u2,θ12]u2,C23[u2,u3,θ23]u2,θ21]du2(2)

M3 copula

C(u1,u2,u3)=-1θ1log{1-(1-e-θ1)-1(1-e-θ1u3){1-[1-(1-e-θ2)-1(1-eθ2u1)(1-e-θ2u2)]θ1/θ2}}(3)

Gaussian copula

C(u1,u2,u3;Σ)=ΦΣ[Φ-1(u1),Φ-1(u2),Φ-1(u3)]=-Φ-1(u1)-Φ-1(u3)1(2π)3/2|Σ|1/2exp(-12wΤΣ-1w)dw(4)Σ=[1ρ12ρ13ρ211ρ23ρ31ρ321]ρij={1,i=jρji,ij-1ρij1

式中:u1,u2,u3为各变量的边缘分布;Φ-1(·)为标准正态分布的逆函数;ΦΣ[Φ-1(u1),Φ-1(u2),Φ-1(u3)]为多元正态分布函数;w为积分变量矢量,w=[w1,w2,w3]T

2 案例分析

以渭河流域华阴站28年的月降雨资料为例,采用游程理论截取干旱历时(LS)、干旱烈度(LD)和烈度峰值(FZ)为干旱特征变量。选取干旱历时服从指数分布,干旱烈度服从gamma分布,干旱峰值服从广义parto分布。经计算,各参数a=1.776 9,ε=0.690 6,α=0.952 7,β=55.443 1,к=-0.423 2,α=44.415 1。相关性见表1所示,表明烈度-峰值相关性最高,其次是历时-烈度,历时-峰值的相关性偏弱。

2.1 copulas参数计算与拟合度检验

本文采用Frank、Gaussian构建二维联合分布函数,Frank pair-copula、Gaussian copula、M3 copula构建三维联合特性分布函数,采用极大似然法估算copulas参数,以RMSE、AIC、BIC为拟合度评价标准,见表2,采用A-D检验[14,15,16,17]多变量联合分布函数,见表3。

由表2可以看出,历时-烈度由Frank构建拟合优度较好,历时-峰值与烈度-峰值由Gaussian构建拟合优度较好。从三维拟合效果来看,Gaussian copula最好,其次是M3 copula。由表3可以看出,在α=0.05,N=5 000,copulas函数均通过A-D检验。

2.2 两变量联合概率与重现期

以历时-烈度两变量联合概率与重现期为例,见图1。

超越概率和条件概率:

Ρ(LSlsLDld)=1-F(ls)-F(ld)+C[F(ls),F(ld)](5)Ρ(LSlsLDld)=1-C[F(ls),F(ld)](6)Ρ(LDld|LSls)=F(ld)-C[F(ls),F(ld)]1-F(ls)(7)

重现期:

Τ0=E(L)1-C[F(ls),F(ld)](8)Τ=E(L)1-F(ls)-F(ld)+C[F(ls),F(ld)](9)

式中:T0为联合重现期;T为同现重现期;E(L)为干旱间隔时间的期望值。

由图1可以看出,Frank比Gaussian的同现超越概率要小,联合超过概率则比Gaussian要大。(c)中Y坐标截距是相应概率值烈度的理论值。从图(d)和(e)等值线可知,Frank的T(LD>200 mm,LS>5月)约为90 a,T(LD>200 mm or LS>5月)约为5 a,Gaussian的T(LD>200 mm,LS>5月)约为30 a,T(LD>200 mm or LS>5月)约为5 a。因此,相同情况下两等值线的历时-烈度的联合重现期均要大于同现重现期。

2.3 三变量联合概率与重现期

三变量不超越概率:

Ρ(LSlsLDldFΖfz)=C[F(ls),F(ld),F(fz)](10)Ρ(LSlsLDldFΖfz)=F(ls)+F(ld)+F(fz)-C[F(ls),F(ld)]-C[F(ls),F(ld)]-C[F(ls),F(fz)]+C[F(ls),F(ld),F(fz)](11)

三变量超越重现期:

Τ0=E(L)Ρ(LSlsLDldFΖfz)=E(L)1-C[F(ls),F(ld),F(fz)](12)

Τ=E(L)Ρ(LSlsLDldFΖfz)=E(L)1-F(ls)-F(ld)-F(fz)+C[F(ls),F(ld)]+C[F(ls),F(ld)]+C[F(ls),F(fz)]-C[F(ls),F(ld),F(fz)](13)

以三变量同现不超越概率和联合超越重现期为例加以说明。在图2中,(a)、(b)和(c)分别给出了在概率值为0.5的情况下,确定峰值(烈度或历时)取值范围时,三维同现不超越概率的等值线图,可知,3种copulas描述同现不超越概率没有显著差异,3条等值线基本重合。(d)、(e)和(f)为联合超过概率重现期(T=10 a)等值线,其中M3 copula和Frank pair-copula基本重合,Gaussian所绘制的结果偏小。(a)、(b)、(c)或(d)、(e)、(f)三维重组可以形成类似于文献[9,17]中的等值面图。

给定历时(LS)情况下的条件概率与重现期:

Ρ(LDldFΖfz|LSls)={C[F(ld),F(fz)]-C[F(ls),F(ld),F(fz)]}1-F(ls)(14)Τ0=11-F(ls)E(L)1-F(ls)-C[F(ld),F(fz)]+C[F(ls),F(ld),F(fz)](15)Τ=11-F(ls)E(L)1-F(ls)-F(ld)-F(fz)+C[F(ls),F(ld)]+C[F(ls),F(fz)]+C[F(ld),F(fz)]-C[F(ls),F(ld),F(fz)](16)

给定历时(LS)和烈度(LD)情况下的条件概率与重现期:

Ρ=F(fz)-C[F(ls),F(fz)]-C[F(ld),F(fz)]+C[F(ls),F(ld),F(fz)]1-F(ls)-F(ld)+C[F(ls),F(ld)](17)Τ=11-F(ls)-F(ld)+C[F(ls),F(ld)]×E(L)1-F(ls)-F(ld)-F(fz)+C[F(ls),F(ld)]+C[F(ls),F(fz)]+C[F(ld),F(fz)]-C[F(ls),F(ld),F(fz)](18)

图3和图4是基于3种copulas绘制的两种条件概率与重现期等值线,Gaussian和Frank pair-copula具有相同的变化趋势,M3 copula具有相似的变化,并穿插于Gaussian和Frank pair-copula之间。由图3可知,在历时为条件的情况下,M3 copula的等值线居于Gaussian和Frank pair-copula之间,进行三维重组亦可以得到相应等值面。由图4可知,在历时和烈度为条件的情况下, Gaussian的等值线居于M3 copula和Frank pair-copula之间。

3 结 语

本文采用Frank和Gaussian copula构建二维干旱联合分布,利用Frank pair-copula,Gaussian copula和M3 copula构建三维干旱联合特性分布,并分别对二维和三维联合分布进行拟合度评价与检验。表明,copulas在多变量联合特性分析中,能够较好地体现出变量间的相关性,具有良好的适用性。对于不同区域,选取的最佳copula会有所不同。Copulas函数作为较为新颖的水文频率研究方法,具有广阔的研究前景。

篇4:python函数局部变量用法实例分析

关键词:变量与函数;概念教学;案例分析;教学反思

中图分类号:G632 文献标识码:B 文章编号:1002-7661(2016)01-247-02

2015年7月22日-8月5日,由兵团教委,教研室组织的中学数学继续教育培训在石河子大学成功举行。本次活动是全疆数学教师的再教育,再深造。其中由兵团教研室杨卫平主任组织的“变量与函数”说课活动引起了大家的关注。作为普通教师的一员,笔者有幸参加了观摩活动,深受启发。下面从以下几个案例提出自己的反思:

案例一:例1、日气温变化图:图18.1.1是某日的气温变化图,根据这张图,你能否得到某个时刻的温度?

从图中我们可以看到,随着时间t(时)的变化,相应地气温T(℃)也随之变化.每一个时间t,都有一个唯一的气温T与之对应.

例2、高尔夫球的轨迹

我们用l标识高尔夫球飞行的水平举例,用h标识高尔夫球的飞行高度.此时高度h随着水平距离l的变化而变化。

例3、水中的波纹

把一块小石头投入池塘中,就会激起一阵阵的波纹。

面积S随着半径r的变化而变化.每一个半径r都有唯一的面积S与之对应.

反思:考虑实例要尽量贴近学生的生活,此案例对课本上提供的例子作了修改,选择了"一日内的温度变化"、"高尔夫球的运动"、"水中的波纹"这样三个例子.如果后两个例子学生在生活中根本没有经验,学生理解起来会有困难。

案例二:例1、《名侦探柯南》中有这样一个情景:柯南根据案发现场的脚印,锁定疑犯的身高.你知道其中的道理吗?”

例2、我们班中同学A与职业相扑运动员,谁的饭量大?你能说明理由吗?

反思:此案例的设计意图是想从学生的生活入手,但现实世界中各种量之间的联系纷繁复杂,应向学生说明我们数学的研究方法是化繁就简,本节课只关注一类简单的问题.当然,这里的问题是作为研究“背景”呈现,教学时应作“虚化”处理,以突出主要内容。否则,教师不易控制课堂节奏,会在这一环节浪费大量时间,这样的引入是否有必要?

案例三:问题一:一辆汽车以60千米/小时的速度匀速行驶,行驶里程为s千米,行驶时间为t小时.

1、请同学们根据题意填写下表:

t/时12345t

s/千米

2、在以上这个过程中,变化的量是______。不变化的量是__________。

3、试用含t的式子表示s=__________,t的取值范围是 _________。

这个问题反映了匀速行驶的汽车所行驶的路程____随行驶时间___的变化过程.

问题二:每张电影票的售价为10元,如果早场售出票150张,午场售出205张,晚场售出310张,三场电影的票房收入各多少元?设一场电影售票x张,票房收入y元。怎样用含x的式子表示y ?

1、请同学们根据题意填写下表:

售出票数(张)早场150午场206晚场310x

收入y (元)

2、在以上这个过程中,变化的量是_____________.不变化的量是__________.

3、试用含x的式子表示y.__y=_________________x的取值范围是__________.

这个问题反映了票房收入_________随售票张数_________的变化过程.

问题三:在一根弹簧的下端悬挂重物,改变并记录重物的质量,观察并记录弹簧长度的变化,探索它们的变化规律.如果弹簧原长10cm,每1kg重物使弹簧伸长0.5cm,设重物质量为mkg,受力后的弹簧长度为l cm,怎样用含m的式子表示l?

1、请同学们根据题意填写下表:

所挂重物(kg)12345m

受力后的弹簧长度l(cm)

2、在以上这个过程中,变化的量是_____________.不变化的量是__________.

3、试用含m的式子表示l. l=___________m的取值范围是_____。

这个问题反映了_________随_________的变化过程.

问题四:圆的面积和它的半径之间的关系是什么?要画一个面积为10cm2的圆,圆的半径应取多少?圆的面积为20cm2呢?30 cm2呢?怎样用含有圆面积s的式子表示圆半径r? 关系式:________

1、请同学们根据题意填写下表:

面积s(cm2)102030s

半径r(cm)

2、在以上这个过程中,变化的量是_____________.不变化的量是__________.

3、试用含s的式子表示r.__r=_________________s的取值范围是__________

这个问题反映了___随___的变化过程.

问题五:用10m长的绳子围成矩形,试改变矩形的长度,观察矩形的面积怎样变化.记录不同的矩形的长度值,计算相应的矩形面积的值,探索它们的变化规律。设矩形的长为xm,面积为sm2,怎样用含有x的式子表示s呢?

1、请同学们根据题意填写下表:

长x(m)1234x

面积s(m2)

2、在以上这个过程中,变化的量是_____________.不变化的量是__________.

3、试用含x的式子表示s=_______________,x的取值范围是 __________。

这个问题反映了矩形的__随__的变化过程.反思:此案例引用了课本的五个实例。第三个例子,由于不少学生在理解“弹簧问题”时面临列函数关系式的困难,可能冲淡对函数概念的学习,对于繁难的概念,我们更应注重为学生构建学生所熟悉的、简单的数学现实,化繁为简、化抽象为形象.过难、过繁的背景会成为学生学习抽象新概念的拦路虎.

综合以上案例分析:

篇5:python函数局部变量用法实例分析

代码如下:

class Foo(object):

static_attr = True

def method(self):

pass

foo = Foo()

这段代码实际上创造了两个对象,Foo和foo。而Foo同时又是一个类,foo是这个类的实例。

在C++里类型定义是在编译时完成的,被储存在静态内存里,不能轻易修改。在Python里类型本身是对象,和实例对象一样储存在堆中,对于解释器来说类对象和实例对象没有根本上的区别。

在Python中每一个对象都有自己的命名空间。空间内的变量被存储在对象的__dict__里。这样,Foo类有一个__dict__, foo实例也有一个__dict__,但这是两个不同的命名空间。

所谓“定义一个类”,实际上就是先生成一个类对象,然后执行一段代码,但把执行这段代码时的本地命名空间设置成类的__dict__. 所以你可以写这样的代码:

代码如下:

>>>class Foo(object):

...bar = 1 + 1

...qux = bar + 1

...print “bar: ”, bar

...print “qux: ”, qux

...print locals()

...

bar:2

qux:3

{‘qux‘: 3, ‘__module__‘: ‘__main__‘, ‘bar‘: 2}

>>>print Foo.bar, Foo.__dict__[‘bar‘]

2 2

>>>print Foo.qux, Foo.__dict__[‘qux‘]

3 3

所谓“定义一个函数”,实际上也就是生成一个函数对象。而“定义一个方法”就是生成一

个函数对象,并把这个对象放在一个类的__dict__中。下面两种定义方法的形式是等价的:

代码如下:

>>>class Foo(object):

...def bar(self):

...return 2

...

>>>def qux(self):

...return 3

...

>>>Foo.qux = qux

>>>print Foo.bar, Foo.__dict__[‘bar‘]

>>>print Foo.qux, Foo.__dict__[‘qux‘]

>>>foo = Foo()

>>>foo.bar()

2

>>>foo.qux()

3

而类继承就是简单地定义两个类对象,各自有不同的__dict__:

代码如下:

>>>class Cheese(object):

...smell = ‘good‘

...taste = ‘good‘

...

>>>class Stilton(Cheese):

...smell = ‘bad‘

...

>>>print Cheese.smell

good

>>>print Cheese.taste

good

>>>print Stilton.smell

bad

>>>print Stilton.taste

good

>>>print ‘taste‘ in Cheese.__dict__

True

>>>print ‘taste‘ in Stilton.__dict__

False

复杂的地方在`.`这个运算符上。对于类来说,Stilton.taste的意思是“在Stilton.__dict__中找‘taste‘. 如果没找到,到父类Cheese的__dict__里去找,然后到父类的父类,等等。如果一直到object仍没找到,那么扔一个AttributeError.”

实例同样有自己的__dict__:

代码如下:

>>>class Cheese(object):

...smell = ‘good‘

...taste = ‘good‘

...def __init__(self, weight):

...self.weight = weight

...def get_weight(self):

...return self.weight

...

>>>class Stilton(Cheese):

...smell = ‘bad‘

...

>>>stilton = Stilton(‘100g‘)

>>>print ‘weight‘ in Cheese.__dict__

False

>>>print ‘weight‘ in Stilton.__dict__

False

>>>print ‘weight‘ in stilton.__dict__

True

不管__init__()是在哪儿定义的, stilton.__dict__与类的__dict__都无关。

Cheese.weight和Stilton.weight都会出错,因为这两个都碰不到实例的命名空间。而

stilton.weight的查找顺序是stilton.__dict__ =>Stilton.__dict__ =>

Cheese.__dict__ =>object.__dict__. 这与Stilton.taste的查找顺序非常相似,仅仅是

在最前面多出了一步。

方法稍微复杂些。

代码如下:

>>>print Cheese.__dict__[‘get_weight‘]

>>>print Cheese.get_weight

>>>print stilton.get_weight

<__main__.Stilton object at 0x7ff820669190>>

我们可以看到点运算符把function变成了unbound method. 直接调用类命名空间的函数和点

运算返回的未绑定方法会得到不同的错误:

代码如下:

>>>Cheese.__dict__[‘get_weight‘]()

Traceback (most recent call last):

File “”, line 1, in

TypeError: get_weight() takes exactly 1 argument (0 given)

>>>Cheese.get_weight()

Traceback (most recent call last):

File “”, line 1, in

TypeError: unbound method get_weight() must be called with Cheese instance as

first argument (got nothing instead)

但这两个错误说的是一回事,实例方法需要一个实例,

所谓“绑定方法”就是简单地在调用方法时把一个实例对象作为第一个参数。下面这些调用方法是等价的:

代码如下:

>>>Cheese.__dict__[‘get_weight‘](stilton)

‘100g‘

>>>Cheese.get_weight(stilton)

‘100g‘

>>>Stilton.get_weight(stilton)

‘100g‘

>>>stilton.get_weight()

‘100g‘

最后一种也就是平常用的调用方式,stilton.get_weight(),是点运算符的另一种功能,将stilton.get_weight()翻译成stilton.get_weight(stilton).

这样,方法调用实际上有两个步骤。首先用属性查找的规则找到get_weight, 然后将这个属性作为函数调用,并把实例对象作为第一参数。这两个步骤间没有联系。比如说你可以这样试:

代码如下:

>>>stilton.weight()

Traceback (most recent call last):

File “”, line 1, in

TypeError: ‘str‘ object is not callable

先查找weight这个属性,然后将weight做为函数调用。但weight是字符串,所以出错。要注意在这里属性查找是从实例开始的:

代码如下:

>>>stilton.get_weight = lambda : ‘200g‘

>>>stilton.get_weight()

‘200g‘

但是

代码如下:

>>>Stilton.get_weight(stilton)

‘100g‘

Stilton.get_weight的查找跳过了实例对象stilton,所以查找到的是没有被覆盖的,在Cheese中定义的方法。

getattr(stilton, ‘weight‘)和stilton.weight是等价的。类对象和实例对象没有本质区别,getattr(Cheese, ‘smell‘)和Cheese.smell同样是等价的。getattr()与点运算符相比,好处是属性名用字符串指定,可以在运行时改变。

__getattribute__()是最底层的代码。如果你不重新定义这个方法,object.__getattribute__()和type.__getattribute__()就是getattr()的具体实现,前者用于实例,后者用以类。换句话说,stilton.weight就是object.__getattribute__(stilton, ‘weight‘). 覆盖这个方法是很容易出错的。比如说点运算符会导致无限递归:

代码如下:

def __getattribute__(self, name):

return self.__dict__[name]

__getattribute__()中还有其它的细节,比如说descriptor protocol的实现,如果重写很容易搞错。

__getattr__()是在__dict__查找没找到的情况下调用的方法。一般来说动态生成属性要用这个,因为__getattr__()不会干涉到其它地方定义的放到__dict__里的属性。

代码如下:

>>>class Cheese(object):

...smell = ‘good‘

...taste = ‘good‘

...

>>>class Stilton(Cheese):

...smell = ‘bad‘

...def __getattr__(self, name):

...return ‘Dynamically created attribute “%s”‘ % name

...

>>>stilton = Stilton()

>>>print stilton.taste

good

>>>print stilton.weight

Dynamically created attribute “weight”

>>>print ‘weight‘ in stilton.__dict__

False

由于方法只不过是可以作为函数调用的属性,__getattr__()也可以用来动态生成方法,但同样要注意无限递归:

代码如下:

>>>class Cheese(object):

...smell = ‘good‘

...taste = ‘good‘

...def __init__(self, weight):

...self.weight = weight

...

>>>class Stilton(Cheese):

...smell = ‘bad‘

...def __getattr__(self, name):

...if name.startswith(‘get_‘):

...def func():

...return getattr(self, name[4:])

...return func

...else:

...if hasattr(self, name):

...return getattr(self, name)

...else:

...raise AttributeError(name)

...

>>>stilton = Stilton(‘100g‘)

>>>print stilton.weight

100g

>>>print stilton.get_weight

>>>print stilton.get_weight()

100g

>>>print stilton.age

Traceback (most recent call last):

File “”, line 1, in

File “”, line 12, in __getattr__

AttributeError: age

篇6:python函数局部变量用法实例分析

这篇文章主要介绍了Python中的map()函数和reduce()函数的用法,代码基于Python2.x版本,需要的朋友可以参考下

Python内建了map()和reduce()函数,

如果你读过Google的那篇大名鼎鼎的论文“MapReduce: Simplified Data Processing on Large Clusters”,你就能大概明白map/reduce的概念。

我们先看map。map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

举例说明,比如我们有一个函数f(x)=x2,要把这个函数作用在一个list [1, 2, 3, 4, 5, 6, 7, 8, 9]上,就可以用map()实现如下:

现在,我们用Python代码实现:

>>>def f(x):... return x * x...>>>map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])[1, 4, 9, 16, 25, 36, 49, 64, 81]

map()传入的第一个参数是f,即函数对象本身。

你可能会想,不需要map()函数,写一个循环,也可以计算出结果:

L = []for n in [1, 2, 3, 4, 5, 6, 7, 8, 9]: L.append(f(n))print L

的确可以,但是,从上面的循环代码,能一眼看明白“把f(x)作用在list的每一个元素并把结果生成一个新的list”吗?

所以,map()作为高阶函数,事实上它把运算规则抽象了,因此,我们不但可以计算简单的f(x)=x2,还可以计算任意复杂的函数,比如,把这个list所有数字转为字符串:

>>>map(str, [1, 2, 3, 4, 5, 6, 7, 8, 9])[‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘]

只需要一行代码。

再看reduce的用法。reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

比方说对一个序列求和,就可以用reduce实现:

>>>def add(x, y):... return x + y...>>>reduce(add, [1, 3, 5, 7, 9])25

当然求和运算可以直接用Python内建函数sum(),没必要动用reduce,

但是如果要把序列[1, 3, 5, 7, 9]变换成整数13579,reduce就可以派上用场:

>>>def fn(x, y):... return x * 10 + y...>>>reduce(fn, [1, 3, 5, 7, 9])13579

这个例子本身没多大用处,但是,如果考虑到字符串str也是一个序列,对上面的例子稍加改动,配合map(),我们就可以写出把str转换为int的函数:

>>>def fn(x, y):... return x * 10 + y...>>>def char2num(s):... return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s]...>>>reduce(fn, map(char2num, ‘13579‘))13579

整理成一个str2int的函数就是:

def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s] return reduce(fn, map(char2num, s))

还可以用lambda函数进一步简化成:

def char2num(s): return {‘0‘: 0, ‘1‘: 1, ‘2‘: 2, ‘3‘: 3, ‘4‘: 4, ‘5‘: 5, ‘6‘: 6, ‘7‘: 7, ‘8‘: 8, ‘9‘: 9}[s]

def str2int(s): return reduce(lambda x,y: x*10+y, map(char2num, s))

也就是说,假设Python没有提供int()函数,你完全可以自己写一个把字符串转化为整数的函数,而且只需要几行代码!

练习

利用map()函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输入:[‘adam‘, ‘LISA‘, ‘barT‘],输出:[‘Adam‘, ‘Lisa‘, ‘Bart‘]。

上一篇:成成不哭了随笔笔记下一篇:耿圩小学教师管理制度