zoukankan      html  css  js  c++  java
  • Python之模块高级话题

    本文大纲:

    1. 在模块中隐藏数据

    有两个模块分别是:
    a.py
    b.py
    现在要在b.py中导入模块a.py。当我们在b.py中导入a.py时,Python会导出a.py顶层所赋值的所有变量名。有时我们会有这样的需求,只要导入a.py中的部分变量名,不用全部导入,这时该怎么做呢?这时就引入我们今天讲的第一点在模块中隐藏数据

    1.1 最小化 from * 的破坏:_X__all__

    当我们使用 from * 在b.py导入a.py模块时,from * 会把a.py全部的变量名都复制过去,有些变量名不是我们需要的,如果a.py和b.py有同名的变量名,a.py的变量名还会覆盖b.py的变量名。
    在a.py文件内的变量名前面放置单下划线,可以防止使用 from * 导入模块时,将其中的变量名复制过去。例如: _name, _age,_address ...

    也可以在模块顶层把变量名的字符串列表赋值给变量 __all__,以达到类似于 _X 的隐藏效果。例如:
    __all__ = ["score", "class", "school"]

    _X__all__ 的区别

    • from * 会把列在 __all__ 列表中的这些变量名复制出来
    • __all__ 指出要复制的变量名,而 _X 是指出不被复制的变量名
    • Python会先找模块内的 __all__ 列表,如果没有定义的话, from * 就会复制出开头没有单下划线的所有变量名。
    • __all___X 只对 from * 语句这种形式有效,它并不是私有声明。

    启用新版本的语言特性 __future__
    Python中的每个新版本都会增加一些新功能,或者在原来版本的基础上做一些修改。有的在当前版本运行正常的代码,可能到了下个新版本就运行不正常了。我们可以使用 __future__ 模块,把下一个版本的新特性引入到当前版本,这样就可以在当前版本测试新版本的特性了。例如:

    from __future__ import featurename

    混合用法模式: __name____main__
    可以把这个文件作为模块导入,并以独立程序的形式运行。每个模块都会有一个 __name__ 属性,Python会自动设置该属性。

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

    结果就是模块可以检测自己的 __name__ ,来确定它是在执行还是在导入。
    下面是一个名为 runme.py 的模块文件。当此文件以程序执行时,就会调用该函数的代码,注意看print(__name__)的结果:

    def tester():
        print("Hello World!")
        print(__name__)
    
    if __name__ == '__main__':
        tester()
    

    运行结果:

    Hello World!
    __main__
    

    下面创建一个 test.py 文件,runme.py以模块的形式导入使用,注意看print(name)的结果:

    import test
    
    test.tester()
    

    运行结果:

    Hello World!
    test
    

    一个模块的 __name__ 变量充当一个使用模式标志,允许它编写成一个可导入的库和一个顶层脚本。

    __name__ 进行单元测试
    下面的函数用于计算一组传进来的数的最小值

    def minmax(test,*args):
        res = args[0]
        for arg in args[1:]:
            if test(arg, res):
                res = arg
        return res
    
    def lessthan(x,y): return x < y
    def grtrthan(x,y): return x > y
    
    print(minmax(lessthan, 4, 2, 1, 5, 6, 3))
    print(minmax(grtrthan, 4, 2, 1, 5, 6, 3))
    

    这个脚本在末端的最后两个print语句是这个程序自我测试的代码。但是这种写法有一个问题,每次这个文件被另一个文件当做模块导入时,都会调用最后两个print语句并输出结果,这对用户体验来说很不好。现做如下改进:

    def minmax(test,*args):
        res = args[0]
        for arg in args[1:]:
            if test(arg, res):
                res = arg
        return res
    
    def lessthan(x,y): return x < y
    def grtrthan(x,y): return x > y
    
    if __name__ == '__main__':  
        print(minmax(lessthan, 4, 2, 1, 5, 6, 3))
        print(minmax(grtrthan, 4, 2, 1, 5, 6, 3))
    
  • 相关阅读:
    Oracle EBS 初始化用户密码
    Oracle EBS FND User Info API
    linux ERROR: ld.so: object '/lib/libcwait.so' from /etc/ld.so.preload cannot be preloaded: ignored.
    linux解压cpio.gz类型文件
    linux删除乱码文件
    linux使用man命令后退出
    linux字符图形界面
    Red Hat linux 如何增加swap空间
    Linux删除文件夹命令
    Linux本地无法登录,远程却可以登录
  • 原文地址:https://www.cnblogs.com/keepcode/p/14429936.html
Copyright © 2011-2022 走看看