python基础知识四

函数是重用的程序段。它们允许你给一块语句一个名称,

然后你可以在你的程序的任何地方使用这个名称多次地运行这个语句块。这被成为调用函数。我们已经使用了许多内建的函数,比如lenrange

 

函数通过def关键字定义。def关键字后跟一个函数的标识符名称,然后跟一对圆括号。圆括号中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。

def sayHello():

  print 'hello world'

sayHello()

  print 'haha','good'

 

事实上我们可以在圆括号中声明一些变量,参数对于函数而言,只是给函数的输入,以便于我们可以传递不同的值给函数,然后得到相应的结果。

 

函数形参

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

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

 

def max(a,b):

if(a>b):

  print a,'is max'

else:

  print b,'is max'

max(20,10)

 

x=5

y=7

max(x,y)

 

我们定义了一个成为printMax的函数,这个函数需要两个形参,叫做ab.

在第一个max中,我们直接把数,即实参提供给函数。

第二个max中,我们使用变量调用函数。max(x,y)使实参x

的值赋给形参a,实参y的值赋给形参b

 

局部变量

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

def func(x):

  print 'x is',x

  x=2

  print 'changer local x to ',x

x=50

func(x)

print 'x is',x

在函数中,我们第一次使用x的值的时候,python使用函数声明的形参的值。接下来我们把2赋给xx是函数的局部变量。所以,但我们在函数内改变x的值的时候,并不会受到影响啊

 

使用global语句

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

你可以使用定义在函数外的变量的值(假设在函数内没有同名的变量).然而,不鼓励这样做,应该避免。

使用global语句可以清楚地表明变量是在外面的块定义的。

def fun():

  global x

  print 'x is',x

  x=2

  print 'change x to',x

x=50

fun()

print 'x is',x

 

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

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

 

默认参数值

对于一些函数,你可能希望它的一些参数是可选的,如果用户不想要为这些参数提供值的话,这些参数就使用默认值。这个功能借助于默认参数值完成。你可以在函数定义的形参名后加上赋值运算符(=)和默认值,从而给形参指定默认参数值。

 

注意,默认参数值应该是一个参数。更加准确的说,默认参数值应该是不可变的。

def say(message,times=1):

  print message*times

say('hello')

say('hello',6)

 

名为say的函数用来打印一个字符串任意所需的次数。如果我们不提供一个值,那么默认地,字符串将只被打印一遍。我们通过给形参times指定默认参数值1来实现这一功能。

 

在第一次使用say的时候,我们只提供一个字符串,函数只打印一次字符串。在第二次使用say的时候,我们提供了字符串和参数5,表明我们想要说这个字符串消息5遍。

 

只有在形参表末尾的那些参数可以有默认参数值,即你不能在声明函数形参的时候,先声明有默认值的形参而后声明没有默认值的形参,这是因为赋给形参的值是根据位置而赋值的。例如,def func(a,b=5)是有效的,但是

def func(a=5,b)是无效的。

 

关键参数

如果你的某个函数有许多参数,而你只想指定其中的一部分,那么你可以通过命名来为这些参数赋值---这被称作关键参数----我们使用名字(关键字)而不是位置来给函数指定实参。

 

这样做有两个优势--,我们不必担心参数的顺序,使用函数变得更加简单了。二、假设其他参数都有默认值,我们可以只给我们想要的那些参数赋值。

 

在第二次使用函数的时候,根据实参的位置变脸a得到值25.根据命名,即关键参数,参数c得到值24。变量b根据默认值为5.

 

在第三次使用func的时候,我们使用关键参数来完全指定参数值。注意,尽管函数定义中,ac之前定义,我们仍然可以在a之前指定参数c的值。

 

return语句用来从一个函数 返回 即跳出函数。我们也可选从函数返回一个值。

 

每个函数都在结尾暗含有return  None语句。通过运行print SomeFunction(),你可以明白这一点,函数someFunction没有使用return语句,如同:

def someFunction():

  pass

pass语句在python 中表示一个空的语句块。

 

DocStrings

python有一个很奇妙的特性,称为文档字符串,它通常被简称为docstring,它可以帮助你的程序文档更加简单易懂,可以尽量使用它。甚至可以在程序运行的时候,从函数恢复文档字符串。

def printMax(x,y):

  '''Print the maximum of two numbers.

 

  the two values must be  integers.'''

  x=int(x)#conver to integers,if possible

  y=int(y)

  if x>y:

    print x,'is maximum'

  else:

    print y,'is maximum'

printMax(3,5)

print printMax.__doc__

 

函数的第一个逻辑行的字符串是这个函数的文档字符串。注意,DocStrings也适用于模块和类。

文档字符串的管理是一个多行字符串,它的首行以大写字符开始,句号结尾。第二行是空行,从第三行开始是详细的描述

 

你可以使用__doc__(双下划线)调用printMax函数的文档字符串属性(属于函数的名称)。记住python把每一样东西都作为对象,包括这个函数。

如果你已经在python中使用过help(),那么你已经看到过DocString 的使用了!它所做的只是抓取函数的__doc__属性,然后整洁地展示给你。你可以对上面这个函数尝试一下。

 

自动化工具也可以以同样的方式从你的程序中提取文档。

对编写的任何正式函数编写文档字符串。

 

 

 

模块

你已经学习了如何在你的程序中定义一次函数而重用代码。如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块。模块基本上就是一个包含了所有你定义的函数和变量的文件。为了在其他程序中重用模块,模块的文件必须以.py为扩展名。

模块可以从其他程序输入 以便利用它的功能。这也是我们使用python标准库的方法。

 

import sys

print 'the command line arguments are:'

for i in sys.argv:

  print i

print '\n\nThe PYTHONPATH is',sys.path,'\n'

 

首先,我们利用import语句 输入sys模块。基本上,这句语句告诉python,我们想要使用这个模块。sys模块包含了与python解释器和它的环境有关的函数。

python执行import sys语句的时候,它在sys.path变量中所列目录中寻找sys.py模块。如果找到了这个文件,这个模块的主块中的语句将被运行,然后这个模块将能够被你使用。注意,初始化过程仅在我们第一次输入模块的时候进行。另外,‘sys''system'的缩写。

 

sys模块中的argv变量通过使用点号指明---sys.argv---这种方法的一个优势是这个名称不会与任何在你的程序中使用的argv变量冲突。另外,它也清晰地表明了这个名称是sys模块的一部分。

sys.argv变量是一个字符串的列表。特别地,sys.argv包含了命令行参数的列表,即使用命令行传递给你的程序的参数。

 

这里,当我们执行python using_sys.py we are arguments的时候,我们使用python命令运行using_sys.py模块,后面跟着的内容被作为参数传递给程序。Python为我们把它存储在sys.argv变量中。

记住,脚本的名称总是sys.argv列表的第一个参数。所以,在这里,'using_sys.py'是sys.argv[0]、'we'是sys.argv[1]、'are'是sys.argv[2]以及'arguments'是sys.argv[3]。注意,Python从0开始计数,而非从1开始。

 

sys.path包含输入模块的目录名列表。我们可以观察到sys.path的第一个字符串是空的---这个空的字符串表示当前目录也是sys.path的一部分,这于pythonpath变量是系统的。

 

输入一个模块是一个比较费时的事情,所以python做了一些技巧,一种方法是创建 字节编译的文件,这些文件以.pyc作为扩展名。字节编译的文件与python变换程序的中间状态有关,当你在下次从别的程序输入这个模块的时候,.pyc文件是十分有用的,它会快得多,因为一部分输入模块所需的处理已经完成了。另外,这些字节编译的文件也是与平台无关的。所以现在知道了。pyc文件事实上是什么了。

 

from..import语句

如果你想要直接输入argv变量到你的程序中(避免在每次使用它时打sys.),那么你可以使用from sys import argv语句。如果你想要输入所有sys模块使用的名字,那么你可以使用from sys import *语句。这对于所有模块都适用。一般来说,应该避免使用from …import而使用import语句,因为这样可以使你的程序更加易读,也可以避免名称的冲突。

 

 

模块的__name__

每个模块都有一个名称,在模块中可以通过语句来找出模块的名称。这在一个场合特别有用---就如前面所提到的,当一个模块被第一次输入的时候,这个模块的主块将被运行。假如我们只想在程序本身被使用的时候运行主块,而在它被别的模块输入的时候不运行主块,我们该怎么做呢?这可以通过模块的__name__属性来完成。

 

if __name__=='__main__':

  print 'this is me'

else:

  print 'sss'

 

输出:

$ python using_name.py

This program is being run by itself

 

$ python

>>> import using_name

I am being imported from another module

>>>

 

每个python模块都有它的__name__,如果它是'__main__',这说明这个模块被用户单独运行,我们可以进行响应的操作。

 

 

制造自己的模块

每个python程序也是一个模块,你已经确保它有.py扩展名了。

def sayhi():

  print 'hi,this is my module speaking.'

version='0.1'

 

这样就是一个模块了。

记住这个模块应该被放置在我们输入它的程序的同一个目录中,或者在sys.path所列目录之一。

import mymodule

 

mymodule.sayhi()

print 'Version', mymodule.version

 

输出:

$ python mymodule_demo.py

Hi, this is mymodule speaking.

Version 0.1

 

注意我们使用了相同的点号来使用模块的成员。python很好地重用了相同的记号。

from mymodule import sayhi, version

# Alternative:

# from mymodule import *

 

sayhi()

print 'Version', version

 

输出完全相同

 

 

dir()函数

你可以使用内建的dir函数来列出模块定义的标识符。标识符有函数、类和变量。

当你为dir()提供一个模块名的时候,它返回模块定义的名称列表。如果不提供参数,它返回当前模块中定义的名称列表。

 

$ python

>>> import sys

>>> dir(sys) # get list of attributes for sys module

['__displayhook__', '__doc__', '__excepthook__', '__name__', '__stderr__',

'__stdin__', '__stdout__', '_getframe', 'api_version', 'argv',

'builtin_module_names', 'byteorder', 'call_tracing', 'callstats',

'copyright', 'displayhook', 'exc_clear', 'exc_info', 'exc_type',

'excepthook', 'exec_prefix', 'executable', 'exit', 'getcheckinterval',

'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding',

'getrecursionlimit', 'getrefcount', 'hexversion', 'maxint', 'maxunicode',

'meta_path','modules', 'path', 'path_hooks', 'path_importer_cache',

'platform', 'prefix', 'ps1', 'ps2', 'setcheckinterval', 'setdlopenflags',

'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout',

'version', 'version_info', 'warnoptions']

>>> dir() # get list of attributes for current module

['__builtins__', '__doc__', '__name__', 'sys']

>>>

>>> a = 5 # create a new variable 'a'

>>> dir()

['__builtins__', '__doc__', '__name__', 'a', 'sys']

>>>

>>> del a # delete/remove a name

>>>

>>> dir()

['__builtins__', '__doc__', '__name__', 'sys']

>>>

首先,我们来看一下在输入的sys模块上使用dir。我们看到它包含一个庞大的属性列表。

 

接下来,我们不给dir函数传递参数而使用它--默认地,它返回当前模块的属性列表。注意,输入的模块同样是列表的一部分。

 

为了观察dir的作用,我们定义一个新的变量a并且给它赋一个值,然后检验dir,我们观察到在列表中增加了以上相同的值。我们使用del语句删除当前模块中的变量/属性,这个变化再一次反映在dir的输出中。

 

关于del的一点注释----这个语句在运行后被用来删除 一个变量/名称。在这个例子中,del  a,你将无法再使用变量a--它就好像从来没有存在过一样。

 

 

模块的用处在于它能为你在别的程序中重用它提供的服务和功能。Python附带的标准库就是这样一组模块的例子。

 

 

posted @ 2015-11-15 19:40  likeshu  阅读(221)  评论(0编辑  收藏  举报