Python中的一些 call、name、main
- python
callable 和__call__
大多数教程都告诉你int()是python的内置函数,然而当你看到int的定义,发现它竟然是类
1 | class int(object): |
不只是int(),还有float(), bool(), str(),很多你以为是函数但实际上却是类,但是呢,当你使用它们时完全察觉不出它们有什么不同,本文不是要和你讨论类和函数,而是要讨论学习callable
什么是callable
一个可callable的对象是指可以被调用执行的对象,并且可以传入参数,
用另一个简单的描述方式,只要可以在一个对象的后面使用小括号来执行代码,那么这个对象就是callable对象,
下面列举callable对象的种类
- 函数
- 类
- 类里的函数
- 实现了__call__方法的实例对象
2.1 函数
1 | def test(): |
函数是python里的一等公民,函数是可调用对象,使用callable函数可以证明这一点
2.2 类
1 | class Stu(object): |
在其他编程语言里,类与函数可以说是两个完全不搭的东西,但在python里,都是可调用对象
2.3 类里的方法
类里的方法也是用def定义的,本质上也是函数
1 | from inspect import isfunction, ismethod |
使用isfunction函数可以判断一个对象是否是函数,run方法也是可调用对象
2.4 实现了__call__方法的实例对象
1 | class Stu(object): |
当你执行stu()时,与调用一个函数有着完全一致的体验,如果不告诉你stu是一个类的实例对象,你还以为stu就是一个函数。
name 和 main
- “__main__” 始终指当前执行模块的名称(包含后缀.py)
- 模块被直接执行的时候,__name__ 等于字符串 “ __main__”
如果该模块 import 到其他模块中,则该模块的 __name__ 等于模块名称(不包含后缀.py) - print(__file__) : 文件绝对路径,c:\Users\13450\Desktop\test.py
- 在Python中,凡是以两个下划线开头,两个下划线结尾的变量叫做“魔法变量”。瓦特?魔法变量?对,你没有听错,就是魔法变量。当然,如果你觉得这个词不好理解的话,你可以简单地认为所谓魔法变量就是Python对象内置天生就有的属性变量,你使用这些变量前不需要自己去定义,直接用就是。当然,既然是天生就有的,你也别去修改它,正常使用就好。
- Python中每个py文件都叫一个模块。系统里面我们经常导入的模块,比如什么os啊,math啊,这些它们的本质都是一个个的py文件。当然,我们自己写的每个py文件也都是一个个的模块,咱们可以把它看成是一个自定义模块。模块既然就是Python文件,那么它就有两种运行方式:一种是直接运行,另外一种是导入别的模块中再运行。
if name == ‘main’:的作用
一个python文件通常有两种使用方法,
第一是作为脚本直接执行,
第二是 import 到其他的 python 脚本中被调用(模块重用)执行。
因此 if name == ‘__main__’: 的作用就是控制这两种情况执行代码的过程,在 if name == ‘__main__’: 下的代码只有在第一种情况下(即文件作为脚本直接执行)才会被执行,而 import 到其他脚本中是不会被执行的。
if name == ‘main’:的运行原理
每个python模块(python文件,也就是此处的 test.py 和 import_test.py)都包含内置的变量__name__,当该模块被直接执行的时候,__name__ 等于文件名(包含后缀 .py );如果该模块 import 到其他模块中,则该模块的 __name__ 等于模块名称(不包含后缀.py)。
而 “__main__” 始终指当前执行模块的名称(包含后缀.py)。进而当模块被直接执行时,__name__ == ‘main’ 结果为真。
当模块A被导入到模块B中时,一旦运行模块B,模块A中的语句会自动被执行一遍,以便加载模块A中的所有函数定义啊、类定义等语句到内存中等待被使用。
‘__getitem__()’
在Python中,__getitem__()
是一个特殊方法(也称为魔术方法或双下方法),它允许一个对象模拟序列或映射类型的行为,使得对象可以通过类似索引的方式访问其元素。这个方法在对象被用作索引操作时被自动调用,例如 obj[key]
。
当你定义一个类并想要让它支持索引操作时,你需要在类中实现 __getitem__()
方法。这个方法接受一个参数,即用作索引的键(对于序列类型通常是整数),并返回相应的值。
下面是一个简单的例子,演示了如何在自定义类中实现 __getitem__()
方法:
1 | class MySequence: |
在这个例子中,MySequence
类有一个 data
属性,它存储了一个序列。__getitem__()
方法被定义为接受一个索引,并返回 data
列表中相应索引位置的元素。如果索引超出了范围,它会引发一个 IndexError
。
__getitem__()
方法还可以接受一个切片对象作为参数,这样你就可以返回一个切片视图或副本,而不是单个元素。例如:
1 | class MySequence: |
在这个例子中,__getitem__()
方法检查传入的参数是否是一个切片对象。如果是,它返回序列的一个切片视图;如果不是,它返回单个元素。
通过实现 __getitem__()
方法,你可以让你的类支持索引和切片操作,从而提高类的灵活性和表达能力。