本文共 11085 字,大约阅读时间需要 36 分钟。
python获取模块函数名
您是否对诸如功能,类,方法,库和模块之类的高级编程术语感到困惑? 您是否在变量范围内挣扎? 无论您是自学成才的程序员还是经过正式培训的代码猴子,代码的模块化都可能使您感到困惑。 但是类和库鼓励模块化代码,而模块化代码可能意味着建立一个多用途代码块的集合,您可以在许多项目中使用它们来减少编码工作量。 换句话说,如果您跟随本文对函数的研究,您将发现更聪明地工作的方法,而更聪明地工作意味着更少的工作。
本文假定您对Python足够熟悉,可以编写和运行简单的脚本。 如果您还没有使用过Python,请先阅读我的文章。
功能是迈向模块化的重要一步,因为它们是形式化的重复方法。 如果程序中需要一次又一次地执行某项任务,则可以将代码分组为一个函数,并根据需要多次调用该函数。 这样,您只需要编写一次代码,但是您可以随意使用它。
这是一个简单函数的示例:
#!/usr/bin/env python3 import time def Timer ( ) : print ( "Time is " + str ( time . time ( ) ) )
创建一个名为mymodularity的文件夹,并将功能代码保存为timestamp.py 。
除此功能外,在mymodularity目录中创建一个名为__init__.py的文件。 您可以在文件管理器或Bash Shell中执行此操作:
$ touch mymodularity/ __init__ . py
现在,您已经在名为mymodularity的Python包中创建了自己的Python库(在Python语言中为“模块”)。 它不是一个非常有用的模块,因为它所做的只是导入时间模块并打印时间戳,但这只是一个开始。
要使用您的函数,请像对待其他任何Python模块一样对待它。 这是一个小型应用程序,它使用mymodularity软件包作为支持来测试Python的sleep()函数的准确性。 将该文件另存为mymodularity目录之外的sleeptest.py (如果将其放入 mymodularity ,则它将成为您程序包中的一个模块,并且您不希望这样做)。
#!/usr/bin/env python3 import time from mymodularity import timestamp print ( "Testing Python sleep()..." ) # modularity timestamp. Timer ( ) time . sleep ( 3 ) timestamp. Timer ( )
在此简单脚本中,您从mymodularity包中调用了时间戳模块(两次)。 从包中导入模块时,通常的语法是从包中导入所需的模块,然后使用模块名称+点号+您要调用的函数的名称 (例如, timestamp.Timer() ) 。
您要两次调用Timer()函数,因此,如果您的时间戳模块比这个简单的示例还要复杂,则可以节省很多重复代码。
保存文件并运行:
$ python3 ./sleeptest. py Testing Python sleep ( ) ... Time is 1560711266.1526039 Time is 1560711269.1557732
Python库的结构似乎令人困惑,但这并不是魔术。 Python经过编程,可以将装满Python代码的文件夹以及__init__.py文件作为一个包对待,并且可以对Python进行编程,以便首先在其当前目录中查找可用的模块。 这就是为什么mymodularity import timestamp中的语句起作用的原因:Python在当前目录中查找名为mymodularity的文件夹,然后查找以.py结尾的时间戳文件。
在此示例中,您所做的与以下较少模块化的版本在功能上相同:
#!/usr/bin/env python3 import time from mymodularity import timestamp print ( "Testing Python sleep()..." ) # no modularity print ( "Time is " + str ( time . time ( ) ) ) time . sleep ( 3 ) print ( "Time is " + str ( time . time ( ) ) )
对于像这样的简单示例,没有真正理由不以这种方式编写睡眠测试,但是编写自己的模块的最好的部分是代码是通用的,因此可以将其重用于其他项目。
通过在调用函数时将信息传递给函数,可以使代码更通用。 例如,假设您要使用模块来测试计算机的睡眠功能,而不是用户的睡眠功能。 更改时间戳记代码,使其接受名为msg的传入变量,该变量将是一个字符串,用于控制每次调用时间戳记时如何呈现时间戳记 :
#!/usr/bin/env python3 import time # updated code def Timer ( msg ) : print ( str ( msg ) + str ( time . time ( ) ) )
现在,您的功能比以前更抽象了。 它仍然会打印时间戳,但是为用户打印的内容是不确定的。 这意味着您在调用函数时需要对其进行定义。
Timer函数接受的msg参数是任意命名的。 您可以调用参数m或message或text或任何您认为有意义的参数。 重要的是,在调用timestamp.Timer函数时,它接受一些文本作为输入,将接收到的所有内容放入变量中,并使用该变量完成其任务。
这是一个新应用程序,用于测试用户正确感知时间流逝的能力:
#!/usr/bin/env python3 from mymodularity import timestamp print ( "Press the RETURN key. Count to 3, and press RETURN again." ) input ( ) timestamp. Timer ( "Started timer at " ) print ( "Count to 3..." ) input ( ) timestamp. Timer ( "You slept until " )
将新应用程序另存为response.py并运行它:
$ python3 ./response. py Press the RETURN key. Count to 3 , and press RETURN again. Started timer at 1560714482.3772075 Count to 3 ... You slept until 1560714484.1628013
现在,新版本的时间戳模块需要一个msg参数。 这很重要,因为您的第一个应用程序已损坏,因为它没有将字符串传递给timestamp.Timer函数:
$ python3 ./sleeptest. py Testing Python sleep ( ) ... Traceback ( most recent call last ) : File "./sleeptest.py" , line 8 , in < module > timestamp. Timer ( ) TypeError : Timer ( ) missing 1 required positional argument: 'msg'
您可以修复sleeptest.py应用程序,使其在模块的更新版本中正常运行吗?
通过设计,函数会限制变量的范围。 换句话说,如果在函数内创建变量,则该变量仅对该函数可用。 如果您尝试使用功能外的功能中出现的变量,则会发生错误。
这是对response.py应用程序的修改,尝试从timestamp.Timer()函数打印msg变量:
#!/usr/bin/env python3 from mymodularity import timestamp print ( "Press the RETURN key. Count to 3, and press RETURN again." ) input ( ) timestamp. Timer ( "Started timer at " ) print ( "Count to 3..." ) input ( ) timestamp. Timer ( "You slept for " ) print ( msg )
尝试运行它以查看错误:
$ python3 ./response. py Press the RETURN key. Count to 3 , and press RETURN again. Started timer at 1560719527.7862902 Count to 3 ... You slept for 1560719528.135406 Traceback ( most recent call last ) : File "./response.py" , line 15 , in < module > print ( msg ) NameError : name 'msg' is not defined
由于未定义msg,因此应用程序返回NameError消息。 这似乎令人困惑,因为您编写了定义msg的代码,但是与Python相比,您对代码的了解更深。 调用函数的代码,无论该函数出现在同一文件中还是作为模块打包,都不知道函数内部会发生什么。 函数独立执行其计算并返回已编程返回的内容。 涉及的任何变量都是局部变量:它们仅存在于函数中,并且仅在函数使用函数才能实现其目的时存在。
如果您的应用程序需要仅包含在函数中的信息,请使用return语句让函数在运行后提供有意义的数据。
他们说时间就是金钱,因此请修改您的时间戳功能以建立一个虚构的计费系统:
#!/usr/bin/env python3 import time def Timer ( msg ) : print ( str ( msg ) + str ( time . time ( ) ) ) charge = .02 return charge
现在, 时间戳模块为每个呼叫收取2美分的费用,但最重要的是,它每次返回时都会收取费用。
这是一个如何使用return语句的演示:
#!/usr/bin/env python3 from mymodularity import timestamp print ( "Press RETURN for the time (costs 2 cents)." ) print ( "Press Q RETURN to quit." ) total = 0 while True : kbd = input ( ) if kbd. lower ( ) == "q" : print ( "You owe $" + str ( total ) ) exit ( ) else : charge = timestamp. Timer ( "Time is " ) total = total+charge
在此示例代码中,可变电荷被指定为timestamp.Timer()函数的端点,因此它将接收函数返回的任何内容。 在这种情况下,该函数返回一个数字,因此使用一个名为total的新变量来跟踪已进行了多少更改。 当应用程序收到退出信号时,它将打印总费用:
$ python3 ./charge. py Press RETURN for the time ( costs 2 cents ) . Press Q RETURN to quit. Time is 1560722430.345412 Time is 1560722430.933996 Time is 1560722434.6027434 Time is 1560722438.612629 Time is 1560722439.3649364 q You owe $ 0.1
函数不必在单独的文件中创建。 如果您只是编写针对一个任务的简短脚本,那么将功能写入同一文件可能更有意义。 唯一的区别是您不必导入自己的模块,但是该函数的工作方式相同。 这是时间测试应用程序的最新版本(作为一个文件):
#!/usr/bin/env python3 import time total = 0 def Timer ( msg ) : print ( str ( msg ) + str ( time . time ( ) ) ) charge = .02 return charge print ( "Press RETURN for the time (costs 2 cents)." ) print ( "Press Q RETURN to quit." ) while True : kbd = input ( ) if kbd. lower ( ) == "q" : print ( "You owe $" + str ( total ) ) exit ( ) else : charge = Timer ( "Time is " ) total = total+charge
它没有外部依赖关系( 时间模块包含在Python发行版中),并且产生的结果与模块化版本相同。 优点是所有内容都位于一个文件中,缺点是您不能在正在编写的其他脚本中使用Timer()函数,除非手动复制并粘贴它。
在函数外部创建的变量没有限制其范围的任何内容,因此将其视为全局变量。
全局变量的一个示例是charge.py示例中的总变量,用于跟踪当前费用。 正在运行的总数是在任何功能之外创建的,因此它绑定到应用程序而不是特定功能。
应用程序中的函数可以访问全局变量,但是要将变量放入导入的模块中,必须以与发送msg变量相同的方式将其发送到导入的模块中。
全局变量之所以方便,是因为它们似乎随时随地都可以使用,但是要跟踪它们的范围并知道哪些变量在不再需要它们后仍在系统内存中徘徊可能很困难(尽管Python通常具有非常好的垃圾回收)。
但是,全局变量很重要,因为并非所有变量都可以是函数或类的局部变量。 现在您知道如何将变量发送到函数并取回值,这很容易。
您已经学到了很多有关函数的知识,因此开始将它们放到脚本中-如果不是作为单独的模块,则不必在一个脚本中多次编写代码块。 在本系列的下一篇文章中,我将介绍Python类。
翻译自:
python获取模块函数名
转载地址:http://epbzd.baihongyu.com/