Python 继承与导入

Python 继承与导入,python,inheritance,python-import,Python,Inheritance,Python Import,这是我在stackoverflow的第一个问题,如果我犯了一两个错误,请让我现在回答。另外,我不是以英语为母语的人,所以也要为一些语法错误做好准备 问题是我完全是个新手,我正在学习通过python和javascript编程。现在,我已经介绍了要点,并且正在试用python中的第一个应用程序,因此这是我第一次练习模块、继承等。对于通过各种模块导入方法/类,我有一些疑问: 我写了一个类(例如class\u 1)。然后我在另一个模块中编写另一个类(例如class_2)类别2继承自类别1。同时,我在类1

这是我在stackoverflow的第一个问题,如果我犯了一两个错误,请让我现在回答。另外,我不是以英语为母语的人,所以也要为一些语法错误做好准备

问题是我完全是个新手,我正在学习通过python和javascript编程。现在,我已经介绍了要点,并且正在试用python中的第一个应用程序,因此这是我第一次练习模块、继承等。对于通过各种模块导入方法/类,我有一些疑问:

  • 我写了一个类(例如
    class\u 1
    )。然后我在另一个模块中编写另一个类(例如
    class_2
    )<代码>类别2继承自
    类别1
    。同时,我在
    类1.\uuuu init\uuu
    方法级别导入了另一个模块中的一些方法。当我编写
    Class_2
    时,我必须在
    \uuu init\uuu
    方法中再次导入在
    Class_1
    中导入的方法,或者继承也意味着在
    Class_1
    级别导入的方法
  • 例如:

    class Class_1(object):
        def __init__(self, args):
        from Module_5.Module_A import method_x
        # Class definition...
    
    class Class_2(Class_1):
        def __init__(self, args):
        from Module_5.Module_A import method_x again?
        # Class definition...
    
  • 我有一个模块,有10个类和30个方法。假设我的两个类需要来自另一个模块的相同方法(例如,
    method\ux
    )(同样,在每个类的
    \uuuuu init\uuu
    方法中)。如果我在模块级别而不是在类级别导入方法,那么对于不使用
    方法的类,是否有一些性能影响?当a)模块中只有一个类需要导入方法,而b)1<[需要该方法的类数]<[模块中的小部分类]需要导入方法时,在模块级或类级导入方法的“通常”或“更具pythonic”的方式是什么(如果在本例中有这种想法)

  • 通常不在类的主体中导入名称。自定义是在文件顶部附近写入导入语句

    from Module_5.Module_A import method_x
    
    class Class_1(object):
        # Class definition...
    
    class Class_2(Class_1):
        # Class definition...
    

    这样做没有显著的性能优势或损失。

    正如Gribouillis所提到的,通常将所有的
    导入
    语句放在文件的开头

    您可以将
    import
    s放在类或函数定义中,但这没有意义,它会使代码更难阅读,这样做没有真正的好处。(事实上,如果您的几个类从同一个模块导入,效率可能会稍低一些,因为您不需要给解释器更多的工作,但这不是什么大问题,因为解释器总是在尝试从磁盘读取模块之前检查模块是否已加载)

    此规则的一个小例外是,如果您的代码仅在文件设计为作为模块导入和直接作为命令行脚本运行时运行。这类文件通常具有

    if __name__ == '__main__':
    
    最后一节,显示仅当文件作为脚本运行时才运行的代码。而该代码可能需要一个模块(例如
    argparse
    ),而其他代码不需要该模块。在这种情况下,可以将这些额外的导入放在该部分的顶部,而不是文件的顶部


    不管你做什么

    import Module_5.Module_A
    

    导入整个
    Module_5.Module_A
    模块,不同之处在于第一个表单将名称
    Module_5.Module_A
    添加到名称空间,第二个表单将名称
    方法_x
    添加到名称空间。当您只需要模块中的几个名称时,从
    导入执行
    是可以的,但这会使代码更难阅读,因为您无法通过查看名称来辨别代码的来源。因此,一般来说,做类似这样的事情比较好

    import Module_5.Module_A as m5A
    
    然后您可以访问它的名称,如下所示:

    m5A.method_x
    
    这样很明显,
    method\ux
    来自
    m5A


    您问:“当我编写
    Class_2
    时,我必须再次导入在
    Class_1
    中导入的方法,否则继承也意味着在
    Class_1级别导入的方法。”。是的,您不需要显式导入第一个模块,除非您希望直接访问其名称。让我用一个更简单的例子来说明

    假设我们有3个模块

    m1.py m2.py m3.py
    如您所见,
    m3.py
    不需要导入
    m1.py
    ,除非您想直接访问
    m1.f1
    m2.f2
    将能够找到
    m1.f1
    ,因为
    m2.py
    中的
    import
    语句,谢谢!只是想说清楚。。。我编辑了我的问题。我的意思是在类的“init”方法,而不是在类的顶部(我认为这没有多大意义)。当然,有时你是自由的,不遵守习俗。例如,我编写一个自包含的函数或类…@joseincadenza实际上,将
    导入
    放在
    \uuuu init\uuu
    方法中更糟糕。现在,不是在执行类定义时执行导入,而是在每次创建类实例时执行导入。当然,一旦磁盘被导入,实际上不会从磁盘加载任何东西,但它仍然效率低下。好的,我相信我完全理解如何处理继承和导入。经验法则:继承总是放在模块的最上面,没有性能优势。最好是导入整个模块,而不是导入特定的类/模块。唯一的例外:作为脚本和导入模块的代码。非常感谢你!
    m5A.method_x
    
    def f1(x):
        return x
    
    import m1
    
    def f2(x):
        return m1.f1(x) * 2
    
    import m2
    
    def f3(x):
        return m2.f2(x) * 3
    
    print(f3(1))