理解Python中的“def main”和“overloading”

时间:2013-03-24 16:47:36

标签: python functional-programming overloading

我经常看到一些代码

def main(A,B)
    some steps

被描述为“主要功能的重载”,在阅读了更具体的Python信息后,我知道这不是真的,因为:

  • Python是一种无损型语言
  • Python中的函数/方法甚至不知道给定参数的类型,也不知道python关注

我也不确定实例和“静态方法”或“类方法”之间是否存在真正的区别,可能它们是相同的,唯一的区别在于使用decoratos,但这可能是与我在使用C / C ++花费了大量时间之后的第一种函数式语法相关。

更重要的是,在Python中,第一个缩进级别被用作入口点(如C / C ++中的main()),所以我不明白为什么你应该在不同于缩进级别的缩进级别定义一个main。真正的第一个。

关于Python关键字的一般想法是关键字具有特殊的语义值而不是真正定义的语法(可能是因为C ++不那么“惯用”,我真的不知道如何解释),它们被用作某种东西的占位符,它们对应用它们的部分赋予特殊含义。还有一些特殊的变量,如__name__,只是存储特殊信息而已。

在我脑中存储了所有这些小信息之后,我仍然没有得到第一个代码示例的真正含义:

  • main()函数有什么特别之处?
  • 如果它不是真正的“主要”
  • ,那么定义像“主要”功能这样的东西是什么意思
  • 如果没有键入,Python如何决定调用哪个函数?
  • 解释器如何读取__init__.py文件和其他文件之间存在差异?

2 个答案:

答案 0 :(得分:1)

回答你的问题:

main()功能

没有什么特别之处。你必须通过以下方式自己调用它:

def main():
    print "This is main"

if __name__ == "__main__":
    main()

为什么要使用main()

您可能这样做的原因是以方便的方式将主要入口点代码保存在一起。例如,如果在main()中创建一些变量,它们将不是全局变量,从而避免污染全局命名空间。如果从另一个模块导入模块(而不是直接将其作为脚本运行),它还会阻止运行main()函数。如果您在导入时不想进行某些初始化(例如,打印消息),这可能很有用,但您确实希望在作为独立脚本运行时执行这些操作。

Python如何决定调用哪个函数

Python在这个意义上不支持“重载”。在给定的命名空间中只能有一个具有给定名称的函数。如果您使用相同的名称创建第二个函数(或在同一个类中具有相同名称的第二个方法),则完全覆盖第一个函数。

__init__.py

这个问题与你的其他人没有关系。但不,它不会以不同的方式处理它们。它在不同的时间处理它们(当你导入包而不是包中的模块时),但它们中的代码运行与任何其他Python文件中的代码相同。

答案 1 :(得分:1)

python中的

main()只是一个函数名。常见的习语

if __name__ == '__main__':
    #do something

是一个快捷方式,用于计算此文件中的代码是作为程序运行而不是作为模块导入。

因为python是无类型的,所以社区非常重视约定和最佳实践。这并没有提供与编译器相同的可预测性,但它有助于防止混乱。可读性是一个核心的蟒蛇价值,这样的习语提供了有价值的结构。

Python在其他语言的意义上不支持函数重载。在强类型语言中,您可能会编写具有相同名称但输入参数不同的同一函数的多个版本:

void DoSomething (int a) {};
void DoSomething (float f) {};
void DoSomething (string s){};

在python中没有相应的习语。在大多数情况下,它是不需要的:对于数字操作,您并不真正关心传入的数字是浮点数,整数还是其他 - 只是它们支持正确的运算符。这就是“鸭子打字”的蟒蛇口号所在 - 如果它像鸭子一样走路,像鸭子一样嘎嘎叫,那就是鸭子。所以python函数惯用look for functions or operators on incoming arguments rather than checking their types

至于静态方法: 在python中,每个实例方法都隐式地将拥有实例作为函数的第一个参数:

class Test(object):
    def __init__(self, arg):
        self.variable = arg
    def example(self):
        print self.variable

fred = Test(999)  # note: no 'self' passed here
fred.example()
>>> 999
joe = Test(-1)
joe.example()
>>> -1

类方法获取类类型而不是实例作为隐式的第一个参数。类方法可以看到类级变量,它们在类范围而不是在实例范围中定义 - 但它们对特定实例一无所知。

class TestCls (Test)
   CLASS_VARIABLE = "hello"
   # other behavior inherited from Test

   @classmethod
   def class_example(cls):
       print cls.CLASS_VARIABLE


barney = TestCls(123)
barney.example()
>>> 123
barney.class_example() # again, no explicit class passed in
>>> 'hello'

静态方法根本没有隐式参数:

class TestStatic (TestCls):
    CLASS_VARIABLE = 'goodbye'
    # inherited stuff again
    @staticmethod
    def static_test():
        print "behold, I have no implicit argument"

静态和类方法也不需要调用实例:

wilma = TestStatic(123)
wilma.static_test()  # you can call from an instance
>>> behold, I have no implicit argument
# or not:
TestStatic.static_test()
>>> behold, I have no implicit argument 
TestStatic.class_example()
>>> goodbye # the method is inherited, but the class variable come from this class