python中的 函数与模块简介

来源:互联网 发布:漏洞扫描平台源码 编辑:程序博客网 时间:2024/05/29 02:19

一、函数

1.概念

一段小型程序,实现特定功能。

例,

>>> 2**3

8

>>> pow(2,3)

8

pow就是函数,是python的一个内建函数,可以直接调用。

自定义函数时一样要遵循先定义后调用的原则,声明时可以不指定返回值的数据类型,没有返回值时默认返回None对象。

2.格式

定义函数的格式如下:

def function(arg1,arg2...):

    "an example for function"

    function_suite/pass

定义函数的关键字为def,函数名字为function,参数在()里面,参数可选,函数下面可加双引号注释,再下面是具体函数语句,如果暂时不想写入具体的函数操作,可以直接用pass关键字代替。

函数名必须以下划线或字母开头,可以包含任意字母、数字或下划线的组合。不能使用任何的标点符号;

函数名是区分大小写的。

函数名不能是保留字。

具体实例:

 def _build_instances(self, message, target_cells, instance_uuids,

            build_inst_kwargs):

        """Attempt to build instance(s) or send msg to child cell."""

        ctxt = message.ctxt

        instance_properties = obj_base.obj_to_primitive(

            build_inst_kwargs['instances'][0])

上面是nova代码中schedule.py中的函数,创建虚机实例的build函数,简单分析下:

函数名字:_build_instances

参数:self, message, target_cells, instance_uuids,

            build_inst_kwargs

注释说明:Attempt to build instance(s) or send msg to child cell.

函数操作:ctxt = message.ctxt 变量赋值

          instance_properties = obj_base.obj_to_primitive(

            build_inst_kwargs['instances'][0]) 调用其他函数为变量赋值

3.调用

函数的调用也可以看成是表达式,结合其他运算符一起使用,如pow()函数的调用:

>>> 10 + pow(2,4)/2

18

>>>

定义函数时可以声明一个默认参数,当调用者没有传参进来时则使用默认参数值:

>>> def foo(debug=1):

...     "test for default argument"

...     if debug:  print 'in debug mode'

...     else: print 'in info mode'     

...

>>> foo()

in debug mode

>>> foo(0)

in info mode

>>> 

4.作用域

函数中对象的作用域:

每个模块都有自已的全局作用域。

函数定义的对象属局部作用域,只在函数内有效,不会影响全局作用域中的对象。

赋值对象属局部作用域,除非使用global关键字进行声明。

Python查找名字的规则:LGB规则

(1)大多数名字引用在三个作用域中查找:先局部(Local),次之全局(Global),再次之内置(Build-in)

>>> a=2

>>> b=2

>>> def test(b):

...     result=a*b

...     return result

...

>>> test(10)

20

可以看出,python先在局部变量里面找,找到b,其次在全局变量里面找到a

所以b的值根据调用者传近来的参数取值,a是全局变量定义的值,result=a*b=20.

 

(2)如想在局部作用域中改变全局作用域的对象,必须使用global关键字。

>>> a=2

>>> b=2

>>> def test():

...     a=3

...     global b

...     b=3

...

>>> test()

>>> print a

2

>>> print b

3

>>>

声明了两个全局变量ab,在test函数中分别对ab赋值,不同的是用global声明b是全局变量,调用test函数后打印出ab的值,发现b的赋值生效;

a被当做局部变量赋值,作用域仅限于test函数内部。

 

(3)global'声明把赋值的名字映射到一个包含它的模块的作用域中。

5.参数

函数的参数是函数与外部沟通的桥梁,它可接收外部传递过来的值。

(1)在一个函数中对参数名赋值不影响调用者。

>>> a=2

>>> def test(a):

...     a=a+1

...     print a

...

>>> test(a)

3

>>> print a

2

>>>

(2)在一个函数中改变一个可变的对象参数会影响调用者。

Pythonheap中分配的对象分成两类:可变对象和不可变对象。所谓可变对象是指,对象的内容是可变的,例如list。而不可变的对象则相反,表示其内容不可变。

不可变对象:整型int,字符串string,浮点型float,元组tuple

可变对象  :列表list,字典dictionary

>>> a=1

>>> b=[1,2]

>>> def test(a,b):

...     a=2

...     b[0]=2

...     print a

...     print b

...

>>> test(a,b)

2

[2, 2]

>>> print a

1

>>> print b

[2, 2]

>>>

(3)不定长参数的使用:

一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数。

语法:

def functionname([formal_args,] *var_args_tuple ):

   "函数_文档字符串"

   function_suite

   return [expression]

formal_args为可选的普通参数;

*var_args_tuple加星号的变量名会存放所有未命名的变量参数,也可以正常传参,不多传参数。

举例:

>>> def test(a,*b):

...     print a

...     for i in b:

...         print i

...

>>> test(10)

10

>>> test(10,20,30,40)

10

20

30

40

>>>

(4)关键字参数

关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

关键字参数就是调用函数的时候指定参数赋值,如下:

>>> def test(a,b):

...     print a

...     print b

...

>>> test(10,20)

10

20

>>> test(b=20,a=10)

10

20

>>>

如果一个函数定义中的最后一个形参有 ** (双星号)前缀,所有正常形参之外的其他的关键字参数都将被放置在一个字典中传递给函数,比如:

>>> def test(a,**b):

...     print a

...     for i in b:

...         print str(b[i])

...

>>> test(23,c='hello')

23

hello

>>> test(23,c='hello',d=0)

23

hello

0

 

6.匿名函数

python 使用 lambda 来创建匿名函数。

lambda只是一个表达式,函数体比def简单很多。

lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。

lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。

虽然lambda函数看起来只能写一行,却不等同于CC++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率。

 

语法

lambda函数的语法只包含一个语句,如下:

lambda [arg1 [,arg2,.....argn]]:expression

 

>>> sum = lambda arg1,arg2: arg1+arg2;

>>> print sum(1,2)

3

>>>

 

二、模块:

1.概念

一种组织形式,将有关系的python代码组织到独立文件中。

类似于cinclude的文件,通过导入来增强python的扩展功能,在文件的最前面(惯例)用import命令导入,导入后可以使用模块中的函数。

例,

>>> import math

>>> math.floor(32.9)

32.0

>>>

先用import导入math模块,然后用“模块.函数”方式来调用floor函数,也可以是“模块.变量”的方式来使用模块内的变量。

也可以用“from 模块 import 函数”的形式直接导入函数,这样调用函数时就不需要每次都加上模块名字

>>> from math import floor

>>> floor(32.9)

32.0

>>>

 

模块除了方法定义,还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。

每个模块有各自独立的符号表,在模块内部为所有的函数当作全局符号表来使用。

所以,模块的作者可以放心大胆的在模块内部使用这些全局变量,而不用担心把其他用户的全局变量搞花。

 

2.__name__属性

一个模块被另一个程序第一次引入时,其主程序将运行。如果我们想在模块被引入时,模块中的某一程序块不执行,我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。

__name__属性等于__main__时说明是模块自身在运行,否则就是被引入。

文件1

#!/usr/bin/python

#Filename:using_name.py

 

if __name__=='__main__':

    print('runing by itself')

else:

    print('from other module')

文件2

#!/usr/bin/python

#Filename:test.py

import using_name

 

分别执行:

[root@tfg-105 guanzy]# python using_name.py

runing by itself

[root@tfg-105 guanzy]# python test.py     

from other module

3.导入

(1)模块与主程序在同一路径下,直接import

(2)模块在主程序所在路径的子目录下,可以在子目录中增加一个空白的__init__.py文件,

该文件使得python解释器将子目录整个也当成一个模块,然后直接通过“import 子目录.模块”导入即可;

[root@tfg-105 guanzy]# ls

name  test.py

[root@tfg-105 guanzy]# cd name/

[root@tfg-105 name]# touch __init__.py

[root@tfg-105 name]# ls

__init__.py  using_name.py

[root@tfg-105 name]# cd ..

[root@tfg-105 guanzy]# ls

name  test.py

[root@tfg-105 guanzy]# vi test.py

#!/usr/bin/python

#Filename:test.py

import name.using_name

[root@tfg-105 guanzy]# python test.py

from other module

(3)模块在主程序的父目录或是其他路径下

先引用sys,对sys.path进行修改,将模块所在目录加到sys.path中。

[root@tfg-105 name]# vi test.py

#!/usr/bin/python

#Filename:test.py

import sys

sys.path.append('/home/guanzy')

import name.using_name

 

[root@tfg-105 name]# python test.py

from other module

原创粉丝点击