python——高级模块话题

1.1 最小化from *的破坏

from *会把所有变量名复制出去,导入者可能得到超出它需要的分布(包括会覆盖导入者内的变量名的变量名)。

在__init__.py中使用__all__则可以保证from *语句只会把__all__列表中的这些变量名复制出来。另外对于模块中以_x形式的变量是指出不被复制的变量名。

1.2混合用法模型:__name__和__main__

每个模块都有一个名为__main__的内置属性,python会自动设置该属性:

  • 如果文件是以顶层程序文件执行,在启动时,__name__就会设备为字符串"__main__"。
  • 如果文件被导入,__name__就会改成客户端所了解的模块名。

结果就是模块可以检测自己的__name__,来确定他是执行还是在导入。

1.3 以__name__进行单元测试

这就是在pycharm中常用的方法:

if __name__ == '__main__':  #这种语法来进行单元测试
    import sys
    if len(sys.argv) ==1:  # sys.argv列表包含了命令行参数,是一个字符串列表,其中你第一个总是将要运行的脚本名
        print('without argv')
    else:
        print(sys.argv[1])

其实,更多的在平时看到的可能是使用argparse模块。argparse是一个命令行工具,具体用法如下:

# learn to using argparse and parse cmdline
def parse_arg():
    # generate a parse object,description will describe what's this parse resolver,
    # you can see this string when using help
    parser =argparse.ArgumentParser(description='this is a demo of argparse')
    # using add_argument to add argument, '-n'  and '-name' are behalf of the same arg
    parser.add_argument('-n','--name',default='Ssozh',help='write down your name')
    # finally , use args get the arguments
    args = parser.parse_args()
    print(args)  # Namespace(name='Ssozh') ,which means -n cannot represent argument name
    name = args.name # using name rather than n
    return name

if __name__ == '__main__':
    name = parse_arg()
    print('hello {}'.format(name))

更详细的可以见另一篇博文:http://vra.github.io/2017/12/02/argparse-usage/

1.4 模块是对象:元程序

因为模型通过内置属性显示了它们的大多数有趣特性,因此,很容易编写程序来管理其他程序。我们通常称这类管理程序为元程序(metaprogram),因为它们是在其他系统之上工作的。

例如,我们编写了一个元程序用来查看模块a的内置属性,而模块(python文件)的内置属性使用属性字典保存,可以使用__dict__进行索引运算。

def listing(module, verbose=True):
    sepline = '-' * 60  # sepline = '________________'
    if verbose:
        print(sepline)
        # name: 123 file: D:SsozhPyCharmlogo_testmodule_demo.py
        print('name:', module.__name__, 'file:', module.__file__) 
        print(sepline)

    count = 0
    for attr in module.__dict__:  # get the attr of module
        # 00)__name__ 
        print('%02d)%s' % (count, attr), end=' ') 
        if attr.startswith('_'):
            print('<built-in name>')  # <built-in name>
        else:
            print(getattr(module, attr))  # this attr maybe variable
        count += 1
    if verbose:
        print(sepline)
        # 123 has 8 names
        print(module.__name__, 'has %d names' % count)
        print(sepline)

1.5 模块设计理念

  • 总是在Python的模块内编写代码。事实上,在交互模型提示符下输入的程序代码,其实是存在于内置模型__main__之内的。交互模型提示符独特之处就在于程序是执行后就立刻丢弃,以及表达式结果是自动打印的。
  • 模块耦合要降到最低:全局变量。就像函数一样,如果编写成闭合的盒子,模块运行得最好。原则就是,模块应该尽可能和其他模块的全局变量无关,除了与从模块导入的函数和类。
  • 最大化模块的黏合性:统一目标。可以通过最大化模块的黏合性来最小化模块的耦合性。如果模块的所有元素都享有共同的目的,就不太可能依赖外部的变量名。
  • 模块应该少去修改其他模块的变量。
原文地址:https://www.cnblogs.com/SsoZhNO-1/p/11404968.html