每天多学一点点,进步不止一丁点,大家好,我是你们的好朋友脑残哥,今天跟大家讨论一下python内置变量、内置函数,以及如何理解脚本中的if __name__ == '__main__' 代码。
python作为一种解释性语言,每个文件在创建时,系统都为它分配好了内置的变量,像__name__就是其中一种,除了__name__,还有其它的内置变量,下面列举了几个比较常用的内置变量及它们的作用:
__doc__:获取到注释内容
__name__:获取到函数的名称
__file__:获取到当前的文件路径
为了加深理解,下面以hello.py脚本为例加以说明。首先在桌面创建hello.py,内容如下:
# -*- encoding=utf-8 -*-
''' this is a hello script.'''
def function1():
'''this is function1 usage'''
print("this is function1")
if __name__ == '__main__':
print("==========print(vars())==============")
print(vars())
print("==========print(__name__)============")
print(__name__)
print("==========print(__doc__)=============")
print(__doc__)
print("==========print(__file__)============")
print(__file__)
print("==========print(function1.__doc__)===")
print(function1.__doc__)
脚本运行结果为:
==========print(vars())==============
{'__name__': '__main__', '__doc__': ' this is a hello script.', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0113DC30>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\amazing\\Desktop\\test.py', '__cached__': None, 'function1': <function function1 at 0x02D196F0>}
==========print(__name__)============
__main__
==========print(__doc__)=============
this is a hello script.
==========print(__file__)============
C:\Users\amazing\Desktop\test.py
==========print(function1.__doc__)===
this is function1 usage
vars()函数
vars()函数作为python的一个内置函数,以字典的形式返回当前模块中所有内置变量及其值,从上面结果可以看到,hello.py中包含有__name__、__doc__、__package__、__loader__等变量,其中__name__的值为'__main__'。
if __name__ == '__main__':
从vars()函数返回的结果来看,内置变量__name__的值是__name__ ,满足条件,所以下面的语句得以执行。有小伙伴就问了,__name__的值是一直等于'__main__'么,当然不是,这就要说到python脚本的执行方式了,我们知道,一个py文件可以直接运行,也可能被别的脚本import进来,形如import hello,或import该脚本中部分函数或其它内容,形如from hello import function1。当脚本被直接运行时,__name__的值为'__main__',当被别的模块调用时,它的值为该脚本自身名字,为了验证,我们在刚刚创建的hello.py脚本同级目录中创建hello2.py,并在hello2.py中引脚hello,代码如下:
# -*- encoding=utf-8 -*-
''' this is a hello2 script.'''
import hello
print(hello.__name__)
print(hello.__doc__)
运行结果如下:
hello
this is a hello script.
[Finished in 0.1s]
这里再补充一下,一般在项目中进行某个模块开发时,经常会使用到if __name__ == '__main__':语句,比如某房价预测系统,其中一个模块是从网上爬取某地址房价数据,但是张三在开发这个脚本时没有足够的信心,要进行模块调试,于是他设计的脚本形如:
# -*- encoding=utf-8 -*-
''' crawl house price module.'''
def crawl_house_price():
print("start crawl...")
if __name__ == '__main__':
crawl_house_price()
即如果该脚本被单独运行,就调用crawl_house_price()函数完成自测试,而当别人import这个脚本时,只会引入crawl_house_price()函数,而由于__name__ != '__main__',所以该函数不会被自动运行。
__doc__
python之所以被广泛使用,与其详细的使用手册密不可分,我们在使用一些系统库或第三方库时里某个函数时,可以很容易地使用如help()方法获取其使用手册,手册里详细地介绍其用法、形参及含义等,如:
>>> import os
>>> help(os.mkdir)
Help on built-in function mkdir in module nt:
mkdir(path, mode=511, *, dir_fd=None)
Create a directory.
If dir_fd is not None, it should be a file descriptor open to a directory,
and path should be relative; path will then be relative to that directory.
dir_fd may not be implemented on your platform.
If it is unavailable, using it will raise a NotImplementedError.
The mode argument is ignored on Windows.
>>> print(os.mkdir.__doc__)
Create a directory.
If dir_fd is not None, it should be a file descriptor open to a directory,
and path should be relative; path will then be relative to that directory.
dir_fd may not be implemented on your platform.
If it is unavailable, using it will raise a NotImplementedError.
The mode argument is ignored on Windows.
可以看到通过help方法,help(os.mkdir)和直接打印print(os.mkdir.__doc__)都可以获取其用法,而这个用法,就是存储在内置变量__doc__中的。
我们自己写的脚本,也可以通过向__doc__中添加模块介绍、使用说明等来增加模块的易用性。怎么实现呢,其实细心的读者有发现,上面的程序里已经有了,这里再次用代码示例加以强调,还以hello.py脚本为例:
# -*- encoding=utf-8 -*-
''' this is a hello script.'''
def function1():
'''this is function1 usage'''
print("this is function1")
if __name__ == '__main__':
print("==========print(__doc__)=============")
print(__doc__)
print("==========print(function1.__doc__)===")
print(function1.__doc__)
在脚本开头的地方”this is a hello script.“会存储到__doc__中,而在函数里的介绍'''this is function1 usage'''会存储到函数function1的__doc__内置变量里,运行以上程序结果为:
==========print(__doc__)=============
this is a hello script.
==========print(function1.__doc__)===
this is function1 usage
[Finished in 0.4s]
__file__
__file__用来打印当前程序所在的绝对位置,不用细说。
大家可以通过内置函数vars()打印看一下自己脚本里有哪些内置变量,它们的值分别是什么。
有的小伙伴电脑上可能装了不止一种Python环境,或同时装了python2.x和python3.x,或使用anaconda创建了多个Python虚拟环境,在运行脚本时经常会出现明明已经安装了某个库,但是import时却找不到,或明明安装的是高版本的库,运行时却报错版本不对,这时我们就可以通过打印内置变量来精确定位脚本中所引用的库具体路径,以numpy为例,我们在脚本里打印某引用路径:
# -*- encoding=utf-8 -*-
''' this is a hello script.'''
import numpy
def function1():
'''this is function1 usage'''
print("this is function1")
if __name__ == '__main__':
print("==========print(vars())=============")
print(vars())
print("==========print(numpy)=============")
print(numpy)
运行结果:
==========print(vars())=============
{'__name__': '__main__', '__doc__': ' this is a hello script.', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x0160DC30>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:\\Users\\amazing\\Desktop\\hello.py', '__cached__': None, 'numpy': <module 'numpy' from 'D:\\soft\\Python\\Python37-32\\lib\\site-packages\\numpy\\__init__.py'>, 'function1': <function function1 at 0x038D96F0>}
==========print(numpy)=============
<module 'numpy' from 'D:\\soft\\Python\\Python37-32\\lib\\site-packages\\numpy\\__init__.py'>
可以看到,由于import numpy,内置变量里多了一个‘numpy'变量,我们打印它的值,就是numpy库所在的位置,这样,就可以一目了然地知道哪个库从哪里来,非常有利于调试程序。
好了,今天介绍到这里,小伙伴们有任何问题都欢迎在下方留言~