• python模块&类的导入.md


    定义模块、包

    在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护。

    为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,

    在Python中,一个.py文件就称之为一个模块(Module)。

    使用模块有什么好处?

    • 最大的好处是大大提高了代码的可维护性。
    • 编写代码不必从零开始。当一个模块编写完毕,就可以被其他地方引用。
    • 使用模块还可以避免函数名和变量名冲突。相同名字的函数和变量完全可以分别存在不同的模块中

    但是如果不同的人编写的模块名相同怎么办?

    为了避免模块名冲突,Python又引入了按目录来组织模块的方法,称为包(Package)。其他的语言可能就叫“命名空间”

    比如一个abc.py的文件就是一个名字叫abc的模块,如果abc与其他模块冲突了,可以选择一个顶层的包mycompany来避免冲突。

    那么引用的时候需要注意,是mycompany.abc而不是abc

    另外需要注意的是在每个包目录下需要有一个__init__.py,否则会把目录当做普通的目录。
    init.py可以是空文件,也可以有Python代码,因为__init__.py本身就是一个模块,而它的模块名就是mycompany。

    自己创建模块时要注意命名,不能和Python自带的模块名称冲突

    使用模块

    使用内置模块

    比如导入sys模块:

    import sys
    

    导入sys模块后,我们就有了变量sys指向该模块,利用sys这个变量,就可以访问sys模块的所有功能。

    sys模块有一个argv变量,用list存储了命令行的所有参数。argv至少有一个元素,因为第一个参数永远是该.py文件的名称

    使用自定义模块

    导入自定义模块可以分为静态导入和动态导入。
    静态导入指的是在文件的开头的时候使用import语句进行一次导入,动态导入是在需要使用的时候再动态的导入,这样就可以在runtime的时候导入模块,而不是在文件的开头一次性导入,更为灵活。

    静态导入

    静态导入主要通过import或者from语句。

    多次import同一个模块,只有第一次有效。

    这两种语句的区别:

    比如下图中,想导入libs.Model.testModelClass模块里面的类testModel
    首先需要在Model文件夹下建立__init__.py文件。

    • import libs.Model.testModelClass: 这些子项必须是包,最后的子项是包或模块。但不能为函数、类或变量,所以实际上没有得到正确的结果。如果想要实例化类,必须将包名写全,也即testModelInstance = libs.Model.testModelClass.testModel()
    • from libsModel.testModelClass import testModel:这种方式item可以是包中的一个子模块或子包,也可以是包中定义的其他命名,像函数、类、变量。所以可以正确引入testModel,可以使用testModelInstance = testModel()进行实例化。

    使用from导入变量,如果和作用域中现有的变量同名,本地变量就会被悄悄地覆盖掉;使用import则没这个问题。

    动态导入

    静态导入类似常量,只能导入名字已经确定的模块。但是有这样一种情况,如果希望定义一个函数,传入导入的模块的包和模块的名称,然后进行导入,使用静态导入是不能实现的。
    动态导入一般可以使用__import__()函数,等价于import语句。

    但是如果要导入模块中的变量或者类需要结合反射。

    先介绍一下getattr()这个python内置函数。

    getattr(object, name[,default]):获取对象object的属性或者方法

    • 如果存在则打印出来
    • 如果不存在,打印出默认值,默认值可选。

    如果是返回的对象的方法,返回的是方法的内存地址,所以只要在后面添加一对括号,就可以运行这个方法。
    比如:

     class test():
     ...     name="xiaohua"
     ...     def run(self):
     ...             return "HelloWord"
    
    

    下面演示一下反射:

    >>> t=test()
    >>> getattr(t, "name") #获取name属性,存在就打印出来。
    'xiaohua'
    >>> getattr(t, "run")  #获取run方法,存在就打印出方法的内存地址。
    

    那么如果要动态的导入上一节里面的那个例子里面的libs.Model.testModel模块中的testModelClass应该怎么办呢?

        libs = __import__('libs.Model.testModelClass');#动态的导入
        model = getattr(libs , "Model");#通过反射一步一步获得模块testModelClass
        testModelClass= getattr(model , 'testModelClass');
        testModel = getattr( testModelClass, "testModel");#通过反射获得类testModel
        obj = testModel();#实例化类
        get = getattr(testModel , "get");#调用testModel类中的get()方法。
        get(obj);
    
    

    有人会说这有什么用?

    比如libs.Model下面可能不是testModelClass,可以是authModelClass的模块,里面的类也相应改变为authModel。那么有没有办法定义一个M(name , method),实现的功能是导入libs.Model.authModelClass下的authModel类并进行实例化。同时调用method方法。

    def M(name, method):
        libs = __import__('libs.Model.'+name+'ModelClass');#动态的导入
        model = getattr(libs , "Model");#通过反射一步一步获得模块testModelClass
        testModelClass= getattr(model , name+'ModelClass');
        testModel = getattr( testModelClass, name+"Model");#通过反射获得类testModel
        obj = testModel();#实例化类
        mtd = getattr(testModel , method);#调用testModel类中的get()方法。
        mtd(obj);
        
    
    

    如果要调用,可以直接使用M("auth","get");,相当于调用引入了模块和类,并进行实例化,然后调用authModel.get()方法。

    安装第三方模块

    上面主要讲的是自己写模块,但是实际上python作为一个”胶水语言“,很多功能已经被别人实现了,我们没有必要自己重复的实现一部分,一定要有”拿来主义“

    安装第三方模块,是通过包管理工具pip完成的。

    注意在安装python的时候,确保安装时勾选了pip和Add python.exe to Path。

    在命令提示符窗口下尝试运行pip,如果Windows提示未找到命令,可以重新运行安装程序添加pip。

    注意:Mac或Linux上有可能并存Python 3.x和Python 2.x,因此对应的pip命令是pip3。

    比如安装excel处理工具xlrd。

    pip install xlrd
    

    但是pip源在国外(你懂的),所以下载会比较慢,可以使用国内的镜像,比如豆瓣。

    pip install -i http://pypi.douban.com/simple/  xlrd --trusted-host pypi.douban.com
    

    模块搜索路径

    当我们试图加载一个模块时,Python会在指定的路径下搜索对应的.py文件,如果找不到,就会报错

    默认情况下,Python解释器会搜索当前目录、所有已安装的内置模块和第三方模块,搜索路径存放在sys模块的path变量中,如果我们要添加自己的搜索目录,有两种方法

    • 直接修改sys.path,添加要搜索的目录:
    >>> import sys
    >>> sys.path.append('/Users/michael/my_py_scripts')
    
    • 设置环境变量PYTHONPATH,该环境变量的内容会被自动添加到模块搜索路径中。设置方式与设置Path环境变量类似。注意只需要添加你自己的搜索路径,Python自己本身的搜索路径不受影响。
    也可以参见简书主页:https://www.jianshu.com/u/482f183ec380
  • 相关阅读:
    给定一个十进制数M,以及需要转换的进制数N。 将十进制数M转化为N进制数
    java计算两条线段交点
    输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m 转载
    全排列 (递归求解+字典序) java 转载
    四大线程池详解(转载)
    生产者消费者简单实现(转载)
    进程 线程通信方式(转载)
    匿名对象和类名为数据类型(java)
    星星(java)
    杨辉三角(java)
  • 原文地址:https://www.cnblogs.com/dy2903/p/7750335.html
Copyright © 2020-2023  润新知