python入口函数,python有入口函数吗

在Python中定义Main函数

目录

成都创新互联-专业网站定制、快速模板网站建设、高性价比伍家岗网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式伍家岗网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖伍家岗地区。费用合理售后完善,十年实体公司更值得信赖。

许多编程语言都有一个特殊的函数,当操作系统开始运行程序时会自动执行该函数。这个函数通常被命名为main(),并且依据语言标准具有特定的返回类型和参数。另一方面,Python解释器从文件顶部开始执行脚本,并且没有自动执行的特殊函数。

尽管如此,为程序的执行定义一个起始点有助于理解程序是如何运行的。Python程序员提出了几种方式对此进行实现。

本文结束时,您将了解以下内容:

Python中的基本main()函数

一些Python脚本中,包含一个函数定义和一个条件语句,如下所示:

此代码中,包含一个main()函数,在程序执行时打印Hello World!。此外,还包含一个条件(或if)语句,用于检查__name__的值并将其与字符串"__main__"进行比较。当if语句为True时,Python解释器将执行main()函数。更多关于Python条件语句的信息可以由此获得。

这种代码模式在Python文件中非常常见,它将作为脚本执行并导入另一个模块。为了帮助理解这段代码的执行方式,首先需要了解Python解释器如何根据代码的执行方式设置__name__。

Python中的执行模式

Python解释器执行代码有两种方式:

更多内容可参考如何运行Python脚本。无论采用哪种方式,Python都会定义一个名为__name__的特殊变量,该变量包含一个字符串,其值取决于代码的使用方式。

本文将如下示例文件保存为execution_methods.py,以 探索 代码如何根据上下文改变行为:

在此文件中,定义了三个对print()函数的调用。前两个打印一些介绍性短语。第三个print()会先打印短语The value __name__ is,之后将使用Python内置的repr()函数打印出__name__变量。

在Python中,repr()函数将对象转化为供解释器读取的形式。上述示例通过使用repr()函数来强调__name__的值为字符串。更多关于repr()的内容可参考Python文档。

在本文中,您将随处可见文件(file),模块(module)和脚本(script)这三个字眼。实际上,三者之间并无太大的差别。不过,在强调代码目的时,还是存在细微的差异:

“如何运行Python脚本”一文也讨论了三者的差别。

基于命令行执行

在这类方法中,Python脚本将通过命令行来执行。

执行脚本时,无法与Python解释器正在执行的代码交互。关于如何通过命令行执行代码的详细信息对本文而言并不重要,但您可以通过展开下框阅读更多有关Windows,Linux和macOS之间命令行差异的内容。

命令行环境

不同的操作系统在使用命令行执行代码时存在细微的差异。

在Linux和macOS中,通常使用如下命令:

美元符号($)之前的内容可能有所不同,具体取决于您的用户名和计算机名称。您键入的命令位于$之后。在Linux或macOS上,Python3的可执行文件名为python3,因此可以通过输入python3 script_name.py来运行python脚本。

在Windows上,命令提示符通常如下所示:

根据您的用户名,之前的内容可能会有所不同,您输入的命令位于之后。在Windows上,Python3的可执行文件通常为python。因此可以通过输入python script_name.py来运行python脚本。

无论哪种操作系统,本文的Python脚本的输出结果都是相同的。因此本文以Linux和macOS为例。

使用命令行执行execution_methods.py,如下所示:

在这个示例中,__name__具有值'__main__',其中引号(')表明该值为字符串类型。

请记住,在Python中,使用单引号(')和双引号(")定义的字符串没有区别。更多关于字符串的内容请参考Python的基本数据类型。

如果在脚本中包含"shebang行"并直接执行它(./execution_methods.py),或者使用IPython或Jupyter Notebook的%run,将会获取相同的结果。

您还可以通过向命令行添加-m参数的方法实现以模块的方式执行。通常情况下,推荐如下方式pip: python3 -m pip install package_name。

添加-m参数将会运行包中__main__.py的代码。更多关于__main__.py文件的内容可参考如何将开源Python包发布到PyPI中。

在三种情况中,__name__都具有相同的值:字符串'__main__'。

技术细节:Python文档中具体定义了__name__何时取值为'__main__'。

当通过标准输入,脚本或者交互提示中读取数据时,模块的__name__将取值为'__main__'。(来源)

__name__与__doc__,__package__和其他属性一起存储在模块的全局命名空间。更多关于属性的信息可参考Python数据模型文档,特别是关于模块和包的信息,请参阅Python Import文档。

导入模块或解释器

接下来是Python解释器执行代码的第二种方式:导入。在开发模块或脚本时,可以使用import关键字导入他人已经构建的模块。

在导入过程中,Python执行指定模块中定义的语句(但仅在第一次导入模块时)。要演示导入execution_methods.py文件的结果,需要启动Python解释器,然后导入execution_methods.py文件:

在此代码输出中,Python解释器执行了三次print()函数调用。前两行由于没有变量,在输出方面与在命令行上作为脚本执行时完全相同。但是第三个输出存在差异。

当Python解释器导入代码时,__name__的值与要导入的模块的名称相同。您可以通过第三行的输出了解这一点。__name__的值为'execution_methods',是Python导入的.py文件。

注意如果您在没有退出Python时再次导入模块,将不会有输出。

注意:更多关于导入在Python中如何工作的内容请参考官方文档和Python中的绝对和相对导入。

Main函数的最佳实践

既然您已经了解两种执行方式上的差异,那么掌握一些最佳实践方案还是很有用的。它们将适用于编写作为脚本运行的代码或者在另一个模块导入的代码。

如下是四种实践方式:

将大部分代码放入函数或类中

请记住,Python解释器在导入模块时会执行模块中的所有代码。有时如果想要实现用户可控的代码,会导致一些副作用,例如:

在这种情况下,想要实现用户控制触发此代码的执行,而不是让Python解释器在导入模块时执行代码。

因此,最佳方法是将大部分代码包含在函数或类中。这是因为当Python解释器遇到def或class关键字时,它只存储这些定义供以后使用,并且在用户通知之前不会实际执行。

将如下代码保存在best_practices.py以证明这个想法:

在此代码中,首先从time模块中导入sleep()。

在这个示例中,参数以秒的形式传入sleep()函数中,解释器将暂停一段时间再运行。随后,使用print()函数打印关于代码描述的语句。

之后,定义一个process_data()函数,执行如下五项操作:

在命令行中执行

当你将此文件作为脚本用命令行执行时会发生什么呢?

Python解释器将执行函数定义之外的from time import sleep和print(),之后将创建函数process_data()。然后,脚本将退出而不做任何进一步的操作,因为脚本没有任何执行process_data()的代码。

如下是这段脚本的执行结果:

我们在这里看到的输出是第一个print()的结果。注意,从time导入和定义process_data()函数不产生结果。具体来说,调用定义在process_data()内部的print()不会打印结果。

导入模块或解释器执行

在会话(或其他模块)中导入此文件时,Python解释器将执行相同的步骤。

Python解释器导入文件后,您可以使用已导入模块中定义的任何变量,类或函数。为了证明这一点,我们将使用可交互的Python解释器。启动解释器,然后键入import best_practices:

导入best_practices.py后唯一的输出来自process_data()函数外定义的print()。导入模块或解释器执行与基于命令行执行类似。

使用__name__控制代码的执行

如何实现基于命令行而不使用Python解释器导入文件来执行呢?

您可以使用__name__来决定执行上下文,并且当__name__等于"__main__"时才执行process_data()。在best_practices.py文件中添加如下代码:

这段代码添加了一个条件语句来检验__name__的值。当值为"__main__"时,条件为True。记住当__name__变量的特殊值为"__main__"时意味着Python解释器会执行脚本而不是将其导入。

条件语块内添加了四行代码(第12,13,14和15行):

现在,在命令行中运行best_practices.py,并观察输出的变化:

首先,输出显示了process_data()函数外的print()的调用结果。

之后,data的值被打印。因为当Python解释器将文件作为脚本执行时,变量__name__具有值"__main__",因此条件语句被计算为True。

接下来,脚本将调用process_data()并传入data进行修改。当process_data执行时,将输出一些状态信息。最终,将输出modified_data的值。

现在您可以验证从解释器(或其他模块)导入best_practices.py后发生的事情了。如下示例演示了这种情况:

注意,当前结果与将条件语句添加到文件末尾之前相同。因为此时__name__变量的值为"best_practices",因此条件语句结果为False,Python将不执行process_data()。

创建名为main()的函数来包含要运行的代码

现在,您可以编写作为脚本由从命令行执行并导入且没有副作用的Python代码。接下来,您将学习如何编写代码并使其他程序员能轻松地理解其含义。

许多语言,如C,C++,Java以及其他的一些语言,都会定义一个叫做main()的函数,当编译程序时,操作系统会自动调用该函数。此函数通常被称为入口点(entry point),因为它是程序进入执行的起始位置。

相比之下,Python没有一个特殊的函数作为脚本的入口点。实际上在Python中可以将入口点定义成任何名称。

尽管Python不要求将函数命名为main(),但是最佳的做法是将入口点函数命名为main()。这样方便其他程序员定位程序的起点。

此外,main()函数应该包含Python解释器执行文件时要运行的任何代码。这比将代码放入条件语块中更好,因为用户可以在导入模块时重复使用main()函数。

修改best_practices.py文件如下所示:

在这个示例中,定义了一个main()函数,它包含了上面的条件语句块。之后修改条件语块执行main()。如果您将此代码作为脚本运行或导入,将获得与上一节相同的输出。

在main()中调用其他函数

另一种常见的实现方式是在main()中调用其他函数,而不是直接将代码写入main()。这样做的好处在于可以实现将几个独立运行的子任务整合。

例如,某个脚本有如下功能:

如果在单独的函数中各自实现这些子任务,您(或其他用户)可以很容易地实现代码重用。之后您可以在main()函数中创建默认的工作流。

您可以根据自己的情况选择是否使用此方案。将任务拆分为多个函数会使重用更容易,但会增加他人理解代码的难度。

修改best_practices.py文件如下所示:

在此示例代码中,文件的前10行具有与之前相同的内容。第12行的第二个函数创建并返回一些示例数据,第17行的第三个函数模拟将修改后的数据写入数据库。

第21行定义了main()函数。在此示例中,对main()做出修改,它将调用数据读取,数据处理以及数据写入等功能。

首先,从read_data_from_web()中创建data。将data作为参数传入process_data(),之后将返回modified_data。最后,将modified_data传入write_data_to_database()。

脚本的最后两行是条件语块用于验证__name__,并且如果if语句为True,则执行main()。

在命令行中运行如下所示:

根据执行结果,Python解释器在执行main()函数时,将依次执行read_data_from_web(),process_data()以及write_data_to_database()。当然,您也可以导入best_practices.py文件并重用process_data()作为不同的数据输入源,如下所示:

在此示例中,导入了best_practices并且将其简写为bp。

导入过程会导致Python解释器执行best_practices.py的全部代码,因此输出显示解释文件用途的信息。

然后,从文件中存储数据而不是从Web中读取数据。之后,可以重用best_practices.py文件中的process_data()和write_data_to_database()函数。在此情况下,可以利用代码重写来取代在main()函数中实现全部的代码逻辑。

实践总结

以下是Python中main()函数的四个关键最佳实践:

结论

恭喜!您现在已经了解如何创建Python main()函数了。

本文介绍了如下内容:

现在,您可以开始编写一些非常棒的关于Python main()函数代码啦!

python语言中有类似C语言或者java中程序执行时的入口方法main(),如果没有那么它是怎么执行的呢?

没有,python是解释型的语言,

看见第一个可以被执行的语句就顺序执行。

比如

def abc(ab): #这是函数,没调用没执行。

print ab

ddd="abcdefg" #赋值语句,执行

print ddd #在标准输出上输出ddd的内容,执行

abc(ddd) 函数调用执行。

【python-C相互调用】python里的dict如何作为参数传入.so中的c语言函数

#include stdio.h

#include stdlib.h

#include Python.h

static PyObject *

wmf_reverse(PyObject *self, PyObject *args, PyObject *kwargs) { 

static char* kwlist[] = {"name", NULL};

char *name = NULL;

PyObject *retval = NULL; 

// 问题1: 只取一个字符串,format应该是"s"

//  if(PyArg_ParseTupleAndKeywords(args,keyds,"isi",kwlist,name))

if (PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, name)) {

retval = (PyObject *)Py_BuildValue("i",1);

printf("%s\n", name);

// 问题2:不要释放

//  free(name); 

} else {

retval = (PyObject *)Py_BuildValue("i",0);

}

return retval;

static PyMethodDef

wmf_methods[] = {

{"reverse",(PyCFunction)wmf_reverse, METH_VARARGS | METH_KEYWORDS, "reverse"},

// 问题3:方法定义表,应该用一条空记录来表示结束。

{NULL, NULL, 0, NULL},

};

// 问题4:没有定义module

static struct PyModuleDef

wmf_module = {

PyModuleDef_HEAD_INIT,

"wmf",      /* name of module */

NULL,       /* module documentation, may be NULL */

-1,         /* size of per-interpreter state of the module,

or -1 if the module keeps state in global variables. */

wmf_methods,

};

// 问题5:入口函数要声明为:PyMODINIT_FUNC

PyMODINIT_FUNC

PyInit_wmf(void) {

// 问题6:Py_InitModule要初始化的是模块,不是方法。所以传方法定义是错误的。

// 另外,python2.x是用Py_Init_module,python3.x改用PyModule_Create了。

// 两者略有差别,自己注意一下吧。这里我用的是python3.x。

//Py_InitModule("wmf",ExtestMethods);

PyObject *m;

m = PyModule_Create(wmf_module);

if (m == NULL) {

return NULL;

}

return m;

}

python语言基础知识有哪些?

python语言基础知识有:

1、Python是一个动态类型语言,可以为变量赋任意值,也可以修改变量的值。

2、字符串:表示一段文本信息,必须使用引号引起来;不能同时混用。

3、导入是将python的一些功能函数放到当前的脚本中使用,不导入的功能无法直接在当前脚本使用。

4、python脚本的入口叫主函数main。

5、每个变量被定义后存入一个内存块。

为什么Python源码中的入口函数是Py

不了方便记忆,没有其它特别的含义。 还有众多的库名也是以PY开头。也是区别于其它语言的标志。

python __name__是什么

Python中的模块(.py文件)在创建之初会自动加载一些内建变量,__name__就是其中之一。Python模块中通常会定义很多变量和函数,这些变量和函数相当于模块中的一个功能,模块被导入到别的文件中,可以调用这些变量和函数。那么这时 __name__ 的作用就彰显了,它可以标识模块的名字,可以显示一个模块的某功能是被自己执行还是被别的文件调用执行,假设模块A、B,模块A自己定义了功能C,模块B调用模块A,现在功能C被执行了:

如果C被A自己执行,也就是说模块执行了自己定义的功能,那么 __name__=='__main__'

如果C被B调用执行,也就是说当前模块调用执行了别的模块的功能,那么__name__=='A'(被调用模块的名字)

其实换一种说法也就是表示当前程序运行在哪一个模块中。

相关推荐:《Python入门教程》

下面举例说明:

首先自定义模块Student,在模块中定义功能Differ()

然后先自身执行,结果如下, __name__=='__main__'

然后B调用执行,结果 __name__=='Student'

上面出两次结果,是因为python中导入模块会先将文件执行一遍,如下图:

到这儿可能有人已经注意到,上面的 __main__ 在python中作可以为函数的入口,而实际工程常用 if __name__=='__main__'来表示整个工程开始运行的入口。此外你如果不想让功能的某部分被别的模块调用执行,比如我自定的模块Student里的‘我的密码是xxx’,只有自己执行才可以打印密码。所有你可以把部分写在if语句里,只有__name__=='__main__'的时候才能执行。这个可以这么理解,在if语句之外代码是最外层的,有点“全局变量”的意思,放入if里面就成了私有的了。


本文标题:python入口函数,python有入口函数吗
URL链接:http://ybzwz.com/article/hegpcd.html