Python学习一

一、偏函数

Python的functools模块提供了很多有用的功能,其中一个就是偏函数(Partial function)。要注意,这里的偏函数和数学意义上的偏函数不一样。

在介绍函数参数的时候,我们讲到,通过设定参数的默认值,可以降低函数调用的难度。而偏函数也可以做到这一点。举例如下:

int()函数可以把字符串转换为整数,当仅传入字符串时,int()函数默认按十进制转换:

>>>int('12345')12345

但int()函数还提供额外的base参数,默认值为10。如果传入base参数,就可以做N进制的转换:

>>>int('12345', base=8)5349

>>>int('12345',16)74565

假设要转换大量的二进制字符串,每次都传入int(x, base=2)非常麻烦,于是,我们想到,可以定义一个int2()的函数,默认把base=2传进去:

defint2(x, base=2):

returnint(x, base)

这样,我们转换二进制就非常方便了:

>>>int2('1000000')64>>>int2('1010101')85

functools.partial就是帮助我们创建一个偏函数的,不需要我们自己定义int2(),可以直接使用下面的代码创建一个新的函数int2:

>>>importfunctools>>>int2 = functools.partial(int, base=2)>>>int2('1000000')64>>>int2('1010101')85

所以,简单总结functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。

注意到上面的新的int2函数,仅仅是把base参数重新设定默认值为2,但也可以在函数调用时传入其他值:

>>>int2('1000000', base=10)1000000

最后,创建偏函数时,实际上可以接收函数对象、*args和**kw这3个参数,当传入:

int2 = functools.partial(int, base=2)

实际上固定了int()函数的关键字参数base,也就是:

int2('10010')

相当于:

kw = { base:2}int('10010', **kw)

当传入:

max2 = functools.partial(max,10)

实际上会把10作为*args的一部分自动加到左边,也就是:

max2(5, 6, 7)

相当于:

args = (10, 5, 6, 7)

max(*args)

结果为10。

小结

当函数的参数个数太多,需要简化时,使用functools.partial可以创建一个新的函数,这个新函数可以固定住原函数的部分参数,从而在调用时更简单。

二、Lambda

1,lambda的一般形式是关键字lambda后面跟一个或多个参数,紧跟一个冒号,以后是一个表达式。lambda是一个表达式而不是一个语句。它能够出现在Python语法不允许def出现的地方。作为表达式,lambda返回一个值(即一个新的函数)。lambda用来编写简单的函数,而def用来处理更强大的任务。

00001.

f =lambdax,y,z : x+y+z

printf(1,2,3)

g =lambdax,y=2,z=3: x+y+z

printg(1,z=4,y=5)

输出结果为:

6

10

2,lambda表达式常用来编写跳转表(jump table),就是行为的列表或字典。例如:

L = [(lambdax: x**2),

(lambdax: x**3),

(lambdax: x**4)]

printL[](2),L[1](2),L[2](2)

D = {'f1':(lambda:2+3),

'f2':(lambda:2*3),

'f3':(lambda:2**3)}

printD['f1'](),D['f2'](),D['f3']()

输出结果为:

4816

568

3,lambda表达式可以嵌套使用,但是从可读性的角度来说,应尽量避免使用嵌套的lambda表达式。

4,map函数可以在序列中映射函数进行操作。例如:

definc(x):

returnx+10

L = [1,2,3,4]

printmap(inc,L)

printmap((lambdax: x+10),L)

输出结果为:

[11,12,13,14]

[11,12,13,14]

5,列表解析可以实现map函数同样的功能,而且往往比map要快。例如:

print[x**2forxinrange(10)]

printmap((lambdax: x**2), range(10))

输出结果为:

[,1,4,9,16,25,36,49,64,81]

[,1,4,9,16,25,36,49,64,81]

6,列表解析比map更强大。例如:

print[x+yforxinrange(5)ifx%2==foryinrange(10)ify%2==1]输出结果为:

[1,3,5,7,9,3,5,7,9,11,5,7,9,11,13]

7,生成器函数就像一般的函数,但它们被用作实现迭代协议,因此生成器函数只能在迭代语境中出现。例如:

defgensquares(N):foriinrange(N):

yieldi**2

foriingensquares(5):

printi,

00001.

输出结果为:

14916

8,所有的迭代内容(包括for循环、map调用、列表解析等等)将会自动调用iter函数,来看看是不是支持了迭代协议。

9,生成器表达式就像列表解析一样,但它们是扩在圆括号()中而不是方括号[]中。例如:

fornumin(x**2forxinrange(5)):

printnum,

00001.

输出结果为:

14916

10,列表解析比for循环具有更好的性能。尽管如此,在编写Python代码时,性能不应该是最优先考虑的

11,没有return语句时,函数将返回None对象。

12,函数设计的概念:

·耦合性:只有在真正必要的情况下才使用全局变量

·耦合性:不要改变可变类型的参数,除非调用者希望这样做

·耦合性:避免直接改变另一个文件模块中的变量

·聚合性:每一个函数都应有一个单一的、统一的目标

13,最后给个默认参数和可变参数的例子:

defsaver(x=[]):

x.append(1)

printx

saver([2])

saver()

saver()

saver()

输出结果为:

[2,1]

[1]

[1,1]

[1,1,1]

三、python2.x与3.x中tkinter调用区别

python 2.x版本中import tkMessageBox

python3.X中变为import tkinter.messagebox

更改相应的import语句,Tkinter改成tkinter,然后

importtkMessageBox

改成

importtkinter.messagebox#对应着tkinter文件夹底下的messagebox.py

改成这种形式要注意接下来在引用的时候必须把import后边的符号全部写出来,否则出错:

messagebox.showinfo("title","hello world")#NameError: name 'messagebox' is not defined

或者改成

fromtkinterimportmessagebox#对应着tkinter文件夹底下的messagebox.py

则可以写成

messagebox.showinfo("title","hello world")

补充两点

1.packages可以认为是文件夹,而modules则可以看作是文件夹下的.py文件,而各色各样的import语句归结起来就是

from packages1.packages2 import modules1

或者

import packages1.packages2.modules1

2.

fromtkinterimport*

并不是将tkinter文件夹下的所有.py文件都import,实际上只是import了__init__.py中的所有对象,比如__init__.py中有个Tk对象,所以在使用了上面这条import语句后,可以直接引用Tk:

root = Tk()

但是如果想使用messagebox.py里的对象,还是得老老实实地引用它:

fromtkinterimportmessagebox#对应着tkinter文件夹底下的messagebox.py

Core Python Programming :路标偏函数GUI应用

# -*- coding: utf-8 -*-

"""

Created on Sat Jul 7 15:02:09 2018

@author: Administrator

"""

#! python3

from functools import partial as pto

from tkinter import *

from tkinter import Tk, Button, X,messagebox

WARN='warn'

CRIT='crit'

REGU='regu'

SIGNS={

'do not enter':CRIT,

'railroad crossig':WARN,

'55\nspeed limit':REGU,

'wrong way':CRIT,

'merging traffic':WARN,

'one way':REGU,

}

critCB=lambda: messagebox.showerror('Error','Error Button Pressed!')

warnCB=lambda: messagebox.showwarning('Warning','Warning Button Pressed!')

infoCB=lambda: messagebox.showinfo('Info','Info Button Pressed!')

top=Tk()

top.title('Road Signs')

Button(top,text='QUIT',command=top.quit,bg='red',fg='white').pack()

MyButton=pto(Button,top)

CritButton=pto(MyButton,command=critCB,bg='white',fg='red')

WarnButton=pto(MyButton,command=warnCB,bg='goldenrod1')

ReguButton=pto(MyButton,command=infoCB,bg='white')

for eachSign in SIGNS:

signType=SIGNS[eachSign]

cmd='%sButton(text=%r%s).pack(fill=X)'%(signType.title(),eachSign,'.upper()'if signType==CRIT else '.title()')

eval(cmd)

top.mainloop()

四、TensorFlow api更改

1、AttributeError:'module' object has no attribute 'SummaryWriter' tf.train.SummaryWriter改为:tf.summary.FileWriter

4、AttributeError:'module'object has no attribute'scalar_summary'tf.scalar_summary('images', images)改为:tf.summary.scalar('images', images) tf.image_summary('images', images)改为:tf.summary.image('images', images) ValueError: Only call `softmax_cross_entropy_with_logits` with named arguments (labels=..., logits=...,...) cifar10.loss(labels, logits) 改为:cifar10.loss(logits=logits, labels=labels) cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits, dense_labels, name='cross_entropy_per_example') 改为:cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=dense_labels, name='cross_entropy_per_example')

5、ValueError: Shapes (2,128,1) and () are incompatible concated = tf.concat(1, [indices, sparse_labels])改为:concated = tf.concat([indices, sparse_labels],1)

6、重大API 变动:

1、TensorFlow models已经被移动到一个单独的github库。

2、除法和模运算符(/,//,%)现在匹配Python(flooring)语义。这也适用于 [tf.div] 和 [tf.mod]。要获取基于强制整数截断的行为,可以使用 [tf.truncatediv] 和 [tf.truncatemod]。

3、现在推荐使用[tf.divide()] 作为除法函数。[tf.div()] 将保留,但它的语义不会回应 Python3或[from future] 机制。

4、tf.reverse() 现在取轴的索引要反转。例如 [tf.reverse(a,[True,False,True])] 现在必须写为 [tf.reverse(a,[,2])]。 [tf.reverse_v2()] 将保持到TensorFlow1.0最终版。

5、[tf.mul,tf.sub ] 和 [tf.neg] 不再使用,改为 [tf.multiply],[tf.subtract] 和 [tf.negative]。

6、[tf.pack] 和 [tf.unpack] 弃用,改为 [tf.stack] 和 [tf.unstack]。7、[TensorArray.pack] 和 [TensorArray.unpack] 在弃用过程中,将来计划启用 [TensorArray.stack] 和 [TensorArray.unstack]。 以下Python函数的参数在引用特定域时,全部改为使用 [axis]。目前仍将保持旧的关键字参数的兼容性,但计划在1.0最终版完成前删除。

7、tf.listdiff已重命名为tf.setdiff1d以匹配NumPy命名。

8、tf.inv已被重命名为tf.reciprocal(组件的倒数),以避免与np.inv的混淆,后者是矩阵求逆。

9、tf.round现在使用banker的舍入(round to even)语义来匹配NumPy。4、tf.split现在以相反的顺序并使用不同的关键字接受参数。我们现在将NumPy order 匹配为tf.split(value,num_or_size_splits,axis)。

10、tf.sparse_split现在采用相反顺序的参数,并使用不同的关键字。我们现在将NumPy order 匹配为tf.sparse_split(sp_input,num_split,axis)。注意:我们暂时要求   tf.sparse_split 需要关键字参数。

11、tf.concat现在以相反的顺序并使用不同的关键字接受参数。特别地,我们现在将NumPy order匹配为tf.concat(values,axis,name)。

13、tf.complex_abs已从Python界面中删除。 tf.abs支持复杂张量,现在应该使用 tf.abs。

14、Template.var_scope属性重命名为.variable_scope

15、SyncReplicasOptimizer已删除,SyncReplicasOptimizerV2重命名为SyncReplicasOptimizer。

16、tf.zeros_initializer()和tf.ones_initializer()现在返回一个必须用initializer参数调用的可调用值,在代码中用tf.zeros_initializer()替换tf.zeros_initializer。

17、SparseTensor.shape已重命名为SparseTensor.dense_shape。与SparseTensorValue.shape相同。

19、使用tf.summary.FileWriter和tf.summary.FileWriterCache替换tf.train.SummaryWriter和tf.train.SummaryWriterCache。

20、从公共API中删除RegisterShape。使用C++形状函数注册。

21、Python API 中的 _ref dtypes 已经弃用。

22、在C++ API(intensorflow/cc)中,Input,Output等已经从tensorflow::ops命名空间移动到tensorflow。

23、将_cross_entropy_with_logits的arg order更改为(labels,predictions),并强制使用已命名的args。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180708G0BOOX00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

同媒体快讯

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励