python 的 __name__

这篇文章The Reason Behind if name == ‘main’ in Python
是出自medium 作者 Jordan Williams

__name__

本文通过两个例子讲解了if name == "main":,在多文件项目中的作用,主要从两个

current_script.py

import other_script 
print('current_script __name__ is set to {} '.format(__name__))

other_script.py

print('other_script __name__ is set to {} '.format(__name__))

输出:

# python3 current_script.py
other_script __name__ is set to other_script
current_script __name__ is set to __main__
# python3 other_script.py
other_script __name__ is set to __main__

name代表当前正在运行的模块/文件名称,直接运行的模块/文件该值为main, 对于导入模块,其值为模块名

java中的main方法

Java中每个类可以main方法如下

public class Application
{
    public static void main(String[] args)
   {
       //construct objects here
   }
}

main方法是一个静态方法,常用对类进行单元测试。

下面是Java核心编程例子

public class StaticTest
{
    public static void main(String[] args){
        Employee[] staff = new Employee[3];
    staff[0] = new Employee("tom", 1000 );
    staff[1] = new Employee("dick", 2000 );
    staff[2] = new Employee("harry", 2000 );

    for (Employee e: staff)
    {
        e.setId();
        System.out.println("name="+e.getName() + 
            ",id=" + e.getId() + 
            ",salary" + e.getSalary());

    }
    int n = Employee.getNextId();
    System.out.println("Next available id = "+n);
    }
}

class Employee
{
    private static int nextId = 1;
    private String name;
    private double salary;
    private int id;

    public Employee(String n, double s)
    {
        name = n ;
        salary = s;
        id = 0;

    }
    public String getName()
    {
        return name;
    }
    public double getSalary()
    {
        return salary;
    }
    public int getId()
    {
        return id;
    }
    public void setId()
    {
        id = nextId;
        nextId ++;
    }
    public static int getNextId()
    {
        return nextId;
    }

    public static void main(String[] args)
    {
        Employee e = new Employee("Harry", 50000);
        System.out.println(e.getName() + " " + e.getSalary());
    }
}

可以看到执行结果,可起到对类进行单元测试的作用

>java StaticTest
name=tom,id=1,salary1000.0
name=dick,id=2,salary2000.0
name=harry,id=3,salary2000.0
Next available id = 4

>java Employee
Harry 50000.0

可以将这个例子用python实现一下

Employee.py

class Employee:
    nextId = 1
    def __init__(self,n,s):
        self.name = n 
        self.salary = s
        self.id = 0;

    def getName(self):
        return self.name

    def getSalary(self):
        return self.salary

    def getId(self):
        return self.id

    def setId(self):
        id = Employee.nextId
        Employee.nextId+=1
    
    def getNextId():
        return Employee.nextId
      

if __name__ == "__main__":
    e = Employee("Harry", 50000)
    print(e.getName(), " ", e.getSalary())

StaticTest.py

from Employee import Employee
if __name__ == "__main__":
    staff = []
    staff.append (Employee("tom", 1000 ))
    staff.append( Employee("dick", 2000 ))
    staff.append( Employee("harry", 2000 ))
    for e in staff:
        e.setId();
        print("name=", e.getName() ,
                ",id={}".format(e.getId()) + 
                ",salary" , e.getSalary());
    n = Employee.getNextId();
    print("Next available id = ", n);

package中的__main__.py

下面把上的的demo做成一个python package

  • 文档结构
packaging_tutorial
├── LICENSE
├── README.md
├── Employee
│   └── __init__.py
│   └── __main__.py
├── pyproject.toml
├── setup.cfg
├── setup.py
└── tests/
  • init.py
class Employee:
    nextId = 1
    def __init__(self,n,s):
        self.name = n
        self.salary = s
        self.id = 0;

    def getName(self):
        return self.name

    def getSalary(self):
        return self.salary

    def getId(self):
        return self.id

    def setId(self):
        id = Employee.nextId
        Employee.nextId+=1

    def getNextId():
        return Employee.nextId
  • main.py
from Employee import Employee
if __name__ == "__main__":
    e = Employee("Harry", 50000)
    print(e.getName(), " " , e.getSalary())
  • pyproject.toml

pyproject.toml: 配置依赖的wheel或其他软件包,来构建系统

[build-system]
requires = [
    "setuptools>=42",
    "wheel"
]
build-backend = "setuptools.build_meta"
  • config metadata

dynamic: setup.py

import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
    long_description = fh.read()

setuptools.setup(
    name="Employee", # Replace with your own username
    version="0.0.1",
    author="garlic",
    author_email="garlic@example.com",
    description="Employee package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/weida/Employee",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
    python_requires='>=3.6',
)

static :setup.cfg

[metadata]
# replace with your username:
name = Employee
version = 0.0.1
url = https://github.com/weida/Employee
author = garlic
author_email = garlic@example.com
classifiers =
    Programming Language :: Python :: 3
    License :: OSI Approved :: MIT License
    Operating System :: OS Independent
description = Employee package
long_description = file: README.md
long_description_content_type = text/markdown

[options]
python_requires = >=3.6
  • README.md
# Example Package

This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.
  • LICENSE
    下面MIT license
Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
  • 生成发行版本
# python3 -m pip install --upgrade build
# python3 -m build
# ls -l
total 8
-rw-r--r--. 1 root root 1882 Feb  8 17:27 Employee-0.0.1-py3-none-any.whl
-rw-r--r--. 1 root root 1566 Feb  8 17:26 Employee-0.0.1.tar.gz
  • build的时候遇到问题
...
no such option: --no-warn-script-location
Traceback (most recent call last):
...

解决方法:修改以下文件注释调--no-warn-script-location

File "/usr/local/lib/python3.6/site-packages/build/env.py", line 142, in install
...
130         with tempfile.NamedTemporaryFile('w+', prefix='build-reqs-', suffix='.txt', delete=False) as req_fil        e:
131             req_file.write(os.linesep.join(requirements))
132         try:
133             cmd = [
134                 self.executable,
135                 '-{}m'.format('E' if sys.version_info[0] == 2 else 'I'),
136                 'pip',
137                 'install',
138 #               '--no-warn-script-location',
139                 '-r',
140                 os.path.abspath(req_file.name),
141             ]
142             subprocess.check_call(cmd)
143         finally:
144             os.unlink(req_file.name)

  • 安装Employee 包
# cd dist
# pip3 install Employee
  • 单独运行模块

当使用 -m 运行模块时,其中的代码会被执行

# python3 -m Employee
 Harry 50000

当然也可以使用StaticTest .py代码调用。

如果需要上传从服务器端下载安装 可以参见下面的文档 官方文档的解释 main — 顶层脚本环境

类似的文章Python if name == main Explained with Code Examples
What is main.py?
这是一篇中文文章Python 中的 if name == ‘main‘ 该如何理解 不错的总结

参考及引用

Photo by  Jη ✿@Jeanne_8L from twitter

Comments are closed.