Python基本语法_函数属性 & 参数类型 & 偏函数的应用

目录

  • 目录
  • 前言
  • 软件环境
  • Python Module的程序入口
  • 函数的属性
  • Python函数的创建
    • 函数的参数
      • 必备参数
      • 缺省参数
      • 命名参数
      • 不定长参数
      • 匿名参数
  • 偏函数的应用

前言

Python除了有丰富的标准库之外,还可以自己定义满足自身需求的类和函数。本篇主要介绍如何创建Python自定义函数。

软件环境

  • 系统
    • UbuntuKylin 14.04
  • 软件
    • Python 2.7.4
    • IPython 4.0.0

Python Module的程序入口

因为一个Python的程序文件同时也是一个模块文件,而且我们希望可以更好的实现类和函数的代码重用性、节省内存资源、提高执行效率。即,我希望主程序仅是在被期望执行的时候才会被执行而不会自动执行。所以我们会在每一个Python module文件中定义一个程序的入口,当我们直接执行Python module的时候会自动执行主程序。当我们一个Python module被别的程序导入时,则仅仅会导入在Python module文件中定义的类和函数。
我们一般会在Python module文件中的主程序前使用下面的一条语句:

if __name__ == '__main__':

__name__是模块的一个属性,其作用是调用当前模块的名称,若此模块是直接执行时,__name__ == ‘__main__’ 。当此模块是被其他程序import时,__name__的值为此模块的名称。
具体的Python module文件结构,请参考:http://blog.csdn.net/jmilk/article/details/48573995
Update: 2016-10-09
Python module程序入口最大的好处在于我们可以利用上述的这个特性来为一个 Module 编写测试代码, 当我们直接运行这个 module 文件的时候, 我们可以通过测试代码的实现来检验我们所定义的函数的输出和输出是否正确, 为每一个由必要测设的 module 文件写上测试代码是一个优秀的程序员所具备的编程习惯.

函数的属性

函数是对程序逻辑进行结构化或过程化的一种编程方法, 函数有助于节省代码空间, 也可以利于保持程序一致性(修改一处, 所有代用都会跟着改变).

函数的属性可以在定义函数时同时定义函数属性, 也可以在函数声明外定义函数属性.
EXAMPLE: 可以通过句点标识符和直接赋值的方法为一个函数添加属性.

In [2]: foo()
in foo()

In [3]: foo.__dict__
Out[3]: {}

In [4]: foo.name = 'jmilkfan'

In [5]: foo()
in foo()

In [6]: foo.__dict__
Out[6]: {'name': 'jmilkfan'}

In [7]: foo.name
Out[7]: 'jmilkfan'

还可以通过下面这种方式来定义函数属性

In [15]: foo.__dict__['age'] = 24

In [16]: foo.__dict__
Out[16]: {'age': 24, 'name': 'jmilkfan'}

In [17]: foo.age
Out[17]: 24

NOTE: 这里可以看出函数对象的 __dict__ 特殊属性包含了函数对象的属性和属性值.

Python函数的创建

一般格式:

def functionName(parameters):
    """Document"""
    函数体
    return [expression] 

创建一个自定义函数需要遵循下面几个规则:
1.函数代码块以def关键词开始,接着函数标识符、圆括号()和代码块起始标识 : 号。
2.任何传入参数和自变量都必须放在()。()内可以用于定义参数。当有多个参数时,使用逗号隔开。
3.函数体的第一行语句可以使用文档字符串"""Document"""一般用作存放函数的使用说明。
在Python中,函数也是一个对象,( )中表示对可调用函数对象的一种调度,可调用的函数对象一定会继承了可调用的方法call( )。这也是用来检查一个函数可否能够被调用的依据。

callable(functionName)

若输出为True,表示对象functionName为可调用函数对象,其继承了call()方法,是一个函数。

In [5]: callable(sys.stdout.write)
Out[5]: True

函数的参数

Python有下面几种函数参数类型:
1.必备参数
2.命名参数
3.缺省参数
4.不定长参数
5.匿名参数

必备参数

必备参数是在自定义函数时,最常见的参数类型。必备参数的使用有下面几点要求:
1.在调用函数时,以形参与实参对应的顺序来确定形参的值并传入函数。
2.调用此函数时,传递的实参的数量必须与声明时定义的形参的数量一致。

In [19]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py

def DoubleCheckInput(input1,input2):
    if input1 == input2:
        print "Your enter the %s" % input1
    else:print "Two input iis not consistent!"
    return "Done"

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your name:")
    enter2 = raw_input("ple enter your name again:")
    DoubleCheckInput(enter1,enter2)

In [20]: run func1Test.py
Ple enter your name:Jmilk
ple enter your name again:Jmilk
Your enter the Jmilk

注意:当传递的参数数目不一致时,会触发下面的异常:

In [23]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py

def DoubleCheckInput(input1,input2):
    if input1 == input2:
        print "Your enter the %s" % input1
    else:print "Two input iis not consistent!"
    return "Done"

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your name:")
    enter2 = raw_input("ple enter your name again:")
    DoubleCheckInput(enter1)

In [24]: run func1Test.py
Ple enter your name:Jmilk
ple enter your name again:Jmilk
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/src/pyScript/func1Test.py in <module>()
     11     enter1 = raw_input("Ple enter your name:")
     12     enter2 = raw_input("ple enter your name again:")
---> 13     DoubleCheckInput(enter1)

TypeError: DoubleCheckInput() takes exactly 2 arguments (1 given)

缺省参数

缺省参数既默认参数。顾名思义,缺省参数可以实现在调用函数却没有指定实参时,可以为形参数提供一个默认值。相对的,当缺省参数对应的实参有传递值时,缺省参数的默认值会被覆盖。从而实参的数目未必一定会与形参的数目一致,因为使用了缺省参数。格式:

def functionName([para1,...,]paras=defaultValues)
In [46]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def DoubleCheckInput(input1,input2='Jmilk'):
    if input1 == input2:
        print "Your enter the %s" % input1
    else:print "Two input iis not consistent!"
    return "Done"

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your name:")
#    enter2 = raw_input("ple enter your name again:")
    DoubleCheckInput(enter1)

In [47]: run func1Test.py
Ple enter your name:Jmilk
Your enter the Jmilk

注意:即便缺省参数会为形参提供一个默认的值,但是在Python的编译过程的语法检查时,参数的匹配依旧是按照顺序传递。所以一般而言,当你希望使用缺省参数的值的时候,需要在定义函数的参数列表时,缺省参数一定要置于必备参数和命名参数之后。避免在参数传递的时候,实参在将参数列表前端的缺省参数覆盖后,却没有实参传递给必备参数。下面是一个例子:

In [56]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def DoubleCheckInput(input1='Jmilk',input2):
    if input1 == input2:
        print "Your enter the %s" % input1
    else:print "Two input iis not consistent!"
    return "Done"

if __name__ == '__main__':
#    enter1 = raw_input("Ple enter your name:")
    enter2 = raw_input("ple enter your name again:")
    DoubleCheckInput(enter2)

In [57]: run func1Test.py
  File "/usr/local/src/pyScript/func1Test.py", line 4
    def DoubleCheckInput(input1='Jmilk',input2):
SyntaxError: non-default argument follows default argument

语法错误:非缺省参数不能在缺省参数之后

命名参数

命名参数也称之为关键字参数, 其仅针对函数的调用, 让调用者通过函数调用中的参数名字赋值来将实参映射到形参, 有下面几个要点:
1.调用时,用赋值的方式来为函数传入参数,调用格式:

functionName(formPara1=actualPara1[,...])

2.可以以任意顺序来指定参数

In [40]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def DoubleCheckInput(input1,input2):
    if input1 == input2:
        print "Your enter the %s" % input1
    else:print "Two input iis not consistent!"
    return "Done"

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your name:")
    enter2 = raw_input("ple enter your name again:")
    DoubleCheckInput(input2=enter2,input1=enter1)

In [41]: run func1Test.py
Ple enter your name:Jmilk
ple enter your name again:Jmilk
Your enter the Jmilk

下面举一个命名参数和缺省参数一结合使用的例子:

In [7]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def printYourEnter(input1,input2='Jmilk',input3='23'):
    print input1
    print input2
    print input3

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your living cities:")
    enter2 = raw_input("ple enter your name:")
    enter3 = raw_input("Ple enter your age:")
    printYourEnter(enter1)

In [8]: run func1Test.py
Ple enter your living cities:BJ
ple enter your name:
Ple enter your age:
BJ
Jmilk
23

在上面的例子中使用了缺省参数,当没有实参传递到函数的时候,形参会使用默认值。但在有些情况中,我们希望可以重新指定形参input3的值,而且希望继续使用input2的默认值。在大多数编程语言中,想要实现上面的要求,必须要使用3个参数来调用函数,即必须重新指定input2的值。但是在Python中因为命名参数类型,所以我们可以突破参数顺序的限制。将上面的例子修改为:

In [13]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def printYourEnter(input1,input2='Jmilk',input3='23'):
    print input1
    print input2
    print input3

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your living cities:")
    enter2 = raw_input("ple enter your name:")
    enter3 = raw_input("Ple enter your age:")
    printYourEnter(input1=enter1,input3=enter3)

In [14]: run func1Test.py
Ple enter your living cities:BJ
ple enter your name:
Ple enter your age:24
BJ
Jmilk
24

可以看见,当我没有传递input2,仅仅是传递了input1、input3,而input2还是使用了默认值,而不会因为没有指定命名参数导致input2被覆盖而input3使用默认值的情况。但是要注意的一点是,即便结合使用了命名参数和缺省参数,仍然无法改变non-default parameter not follows the default parameter的语法规则。

不定长参数

不定长参数也称之为参数组或冗余参数, 当你希望一个函数可以接受处理比当初声明定义函数时更多的参数,可以使用不定长参数。即,实现了函数的参数冗余。当传递的实参数目比函数的形参更多时,一般会报错。但函数中的不定长参数可以用来吸收多余的参数。注意:不定长参数仅允许放到函数形参列表的最后。格式:

def functionName([para1,para2,...,]*indefinitePara):

def functionName([para1,para2,...,]**indefinitePara):

def functionName([para1,para2,...,]*indefinitePara1, **indefinitePara2):

其中的 “*” 标识了不定长参数为 (非关键字参数) 会存储所有非关键字的冗余参数(没有在实参列表内指定关键字,EG. name='Jmilkfan'),并将冗余的参数存储为Tuple类型对象, 也可以向该形参传递一个 Tuple 类型的参数组, 两者的效果是一样的. 只是前者在函数内处理成 Tuple 的形式, 后者在调用之前就已经整理成 Tuple 了
Example1:

In [23]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
import sys
def printYourEnter(input1,*indePara):
    print input1
    print indePara
    for var in indePara:
        print var

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your living cities:")
    enter2 = raw_input("ple enter your name:")
    enter3 = raw_input("Ple enter your age:")
    printYourEnter(enter1,enter2,enter3)

In [24]: run func1Test.py
Ple enter your living cities:BJ
ple enter your name:Jmilk
Ple enter your age:23
BJ
('Jmilk', '23')
Jmilk
23

上面例子的函数中使用了不定长参数*indePara,来存放enter2多余的enter3两个实参。并且是以元组的数据类型来存储。
Example2:
而 “**” 表示为一个 (关键字参数),以字典的数据类型来存储冗余实参, 也可以向该形参传递一个 Dict 类型的实参。

In [4]: %pycat func1Test.py
#!/usr/bin/env python
#Filename:func1Test.py
def printYourEnter(input1,**indePara):
    print input1
    print indePara

if __name__ == '__main__':
    enter1 = raw_input("Ple enter your living cities:")
    enter2 = raw_input("ple enter your name:")
    enter3 = int(raw_input("Ple enter your age:"))
    printYourEnter(enter1,name=enter2,age=enter3)

In [5]: run func1Test.py
Ple enter your living cities:BJ
ple enter your name:Jmilk
Ple enter your age:23
BJ
{'age': 23, 'name': 'Jmilk'}

在调用函数时,使用key=value的映射关系元素,传递实参。本质上是传递了key的引用和value的数据两个值,并且传递到函数中的**indePara字典类型。要注意这与命名参数的区别,命名参数是为了可以乱序传递实参,而不定长参数是为了将多余的实参保存在函数中的Tuple或Dictionary类型对象中。
注意:以Tuple或Dic作为形参吸收实按冗余时,若实参中均没有多余的元素或没有映射关系元素时,会自动的为函数中的Tuple或Dic类型对象填入空值,避免报错。

In [9]: %pycat test.py
#!/usr/bin/env python
def test(x,*args,**kwargs):
    print x
    print args
    print kwargs
test(1)

In [10]: run test.py
1
()
{}

还需要注意的是:实参的映射关系元素中的key,不可以与已经存在的普通形参同名。否则会报错

In [13]: %pycat test.py
#!/usr/bin/env python
def test(x,**kwargs):
    print x
    print kwargs

test(1,x=1,y=2)

In [14]: run test.py
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/src/pyScript/test.py in <module>()
      4     print kwargs
      5
----> 6 test(1,x=1,y=2)

TypeError: test() got multiple values for keyword argument 'x'

主要是避免命名参数和不定长参数的冲突。

匿名参数

匿名函数,即lambda函数。此函数能够快速的创建出单行最小行函数并用于任何需要函数的地方,使用匿名参数有下面几个要点:
1.无须使用def关键字来进行声明。
2.lambda函数可以接受任何数量的实参,但只会且仅返回一个表达式的值。
3.lambda函数不能包含有命令和多个表达式。
4.不能直接调用print语句,因为lambda函数是单行函数且此行只能为表达式。
5.lambda函数拥有自己的命名空间,不能访问除自身参数列表之外的全局命名空间内的参数。
6.lambda最大的优势在于,可以不占用栈内存从而增加执行效率。
lambda函数的定义格式:

functionName = lambda [arg1[,arg2,...]]:expression

调用格式:

functionName(arg1[,arg2,..])

Example:

In [76]: %pycat lamTest.py
#!/usr/bin/env python
#Filename:lamTest.py
n = lambda x,y:x*y
print type(n)
print type(n(2,3))
print n(2,3)

In [77]: run lamTest.py
<type 'function'>
<type 'int'>
6

lambda在定义时会返回一个需要接收的函数对象,在调用后会返回一个类型对象。

偏函数的应用

偏函数的概念:就是将函数式编程、缺省参数和冗余参数结合在一起,将任意数量(顺序)的参数转化为另一个带有剩余参数的函数对象,从而实现截取函数功能(偏向)的效果。
NOTE:偏函数需要 functools Module 的支持。
EXAMPLE 1:将二进制数转化为十进制

In [1]: int('10101010', base=2)
Out[1]: 170

一般而言我们会使用上述的方式来执行,但有些时候会觉得能不能将 int() 函数的 base 参数临时的设置成缺省参数呢?这样的话就可以获得一个专门为了实现 *将二进制数转化为十进制
* 功能的函数了。下面就是偏函数其中一个小的应用实例:

In [2]: from functools import partial

In [3]: baseTwo = partial(int, base=2)

In [5]: baseTwo('10101010')
Out[5]: 170

将 int() 函数的 base 参数定义为缺省参数,并返回给一个新的变量,这样就像是生成了一个新的函数,EG.
baseTwo(x) == int(x, base=2)

除此之外,我们还可以利用函数属性的特性来为这个 “新定义” 的函数编写文档。

In [6]: baseTwo.__doc__ = 'Convert base 2 string to an int.'

In [8]: baseTwo.__doc__
Out[8]: 'Convert base 2 string to an int.'
时间: 2024-12-24 08:21:59

Python基本语法_函数属性 &amp; 参数类型 &amp; 偏函数的应用的相关文章

Python基本语法_函数_参数的多类型传值

前言 上一篇主要介绍了Python函数的参数类型,本篇继续学习Python函数多类型传值. 目录 前言 目录 软件环境 参数的多类型传值 向函数传递Tuple 向函数传递List 向函数传递Dictionary 软件环境 系统 UbuntuKylin 14.04 软件 Python 2.7.4 IPython 4.0.0 参数的多类型传值 一般而言,形参和实参的数量要一致.但是当实参为序列数据类型时,我们可以将多个实参传递到形参中. 我们可以在实参列表中以 * 或者 ** 标识符来限制传入的实参

Python基本语法_函数_返回值

目录 目录 前言 函数的返回值 在函数中Return和Print的区别 函数中的文档 前言 函数的返回值是函数重要的组成部分.函数的根本在于实现程序的部分功能,所以很多时候我们需要将函数执行后的结果返回给程序再由程序作出进一步的操作.可以说是函数的返回值令函数与函数之间,函数与主程序之间更加紧密的联系起来. 函数的返回值 在Python的函数中都有一个返回值,默认为None.也可以使用return value语句来定义一个且只能定义一个可为任意类型的返回值.但是我们能够返回一个序列类型的对象,来

Python基本语法_异常处理详解

目录 目录 异常 异常类型 异常处理 触发异常raise 传递异常 assert语句触发异常 捕获异常tryexceptelse 捕捉多个异常 tryfinally语句 自定义异常 withas触发异常自动关闭资源 as获取异常信息 异常参数 traceback追踪异常 sysexc_info获取异常信息 最后 异常 异常即非正常状态,在Python中使用异常对象来表示异常.若程序在编译或运行过程中发生错误,程序的执行过程就会发生改变,抛出异常对象,程序流进入异常处理.如果异常对象没有被处理或捕

Python基本语法_集合set/frozenset_内建方法详解

目录 目录 前言 软件环境 可变集合Set set函数创建集合 创建空集合 集合元素的唯一性 集合推导式 set类型对象的内置方法 add增加一个元素 remove删除一个元素 pop随机删除并返回一个元素 discard删除一个元素 clear 不可变集合Frozenset frozenset创建一个frozenset集合 set能够与frozenset作比较 set和frozenset的混合运算 frozenset集合作为dic的key setfrozenset共有的内建函数 interse

Python基本语法_基本数据类型_序列类型详解

目录 目录 序列 序列的标准操作符 切片操作符 一个例子 字符串的连接 序列的功能函数 enumerate 枚举出序列对象的元素 len 获取序列对象的长度 min 取出sequence中的最小值 max 取出sequence中的最大值 reversed 返回一个逆序访问的迭代器 sorted 序列的排序 sum 计算序列中的各项元素和 zip 混合两个序列对象 all 检测sequence中各项元素是否均为True any 检测序列中的任意元素是否为True 序列 序列是一类基本数据类型(字符

Python基本语法_文件操作_读写函数详解

目录 目录 软件环境 file文件对象 open文件操作 读文件 read读取所有文件内容 readline获取一行内容 readlines读取所有文件内容 readreadlinereadlines的区别 写文件 write writelines写入多行内容 write和writelines的区别 将标准输出重定向写入到指定文件 文件指针 tell获取当前文件指针位置 truncate截断文件 seek转移文件指针 最后 软件环境 系统 UbuntuKylin 14.01 软件 Python

Python基本语法_输入/输出语句详解

目录 目录 前言 输入 raw_input input raw_input 和 input 的区别 输出 print print 基本格式化输出 print复杂格式化输出 flags标志位 width宽度 precision精度 dictionaryName字典 print自动换行底层实现 最后 前言 程序最基本需要的两个要素,一个是数据,另外一个便是逻辑.而控制语句在程序中扮演的角色便是实现程序的逻辑,即数据的导向和对数据的操作.当然,这并不代表,程序中的数据的行为只能通过控制语句来实.但在P

Python基本语法_基本数据类型_数值型详解

目录 目录 软件环境 Python变量调用的过程 数值型 删除一个数值类型对象 布尔型 Bool 标准整型 Int 长整型 双精度浮点型 Float 复数 数值类型对象的内建功能函数 absNumber 求Number的绝对值 coercex y 将x y转换为同一种数值类型 divmodx y 除法-取余运算的结合 pow 指数运算或将结果取余 round 浮点型的四舍五入运算和求精度 仅用于整型对象的函数 数值型相关模块推荐 软件环境 系统 CentOS 7 软件 Python 2.7.5

Python基本语法_变量作用域LEGB

目录 目录 软件系统 变量的作用域 高级语言对数据类型的使用过程 作用域的产生 作用域的类型 Llocal局部作用域 Eenclosing嵌套作用域 Gglobal全局作用域 Bbuilt-in内置作用域 变量名解析LEGB法则 实例说明 对变量的引用 对变量的修改 global关键字 nonlocal关键字 命名空间和作用域的区别 软件系统 系统 Ubuntu 14.04 软件 Python 2.7.3 IPython 4.0.0 变量的作用域 在Python程序中创建.改变.查找变量名时,都