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))
    
  • 相关阅读:
    149. Max Points on a Line(js)
    148. Sort List(js)
    147. Insertion Sort List(js)
    146. LRU Cache(js)
    145. Binary Tree Postorder Traversal(js)
    144. Binary Tree Preorder Traversal(js)
    143. Reorder List(js)
    142. Linked List Cycle II(js)
    141. Linked List Cycle(js)
    140. Word Break II(js)
  • 原文地址:https://www.cnblogs.com/keepcode/p/14429936.html
Copyright © 2011-2022 走看看