__init__() VS __init__.py
定义类的时候,若是添加init方法,那么在创建类的实例的时候,实例会自动调用这个方法,一般用来对实例的属性进行初使化。
Python 类中定义__init__()后,执行实例化的过程,新建的实例本身,连带其中的参数,会一并传给 __init__()函数自动并执行它。所以 __init__()函数的参数列表会在开头多出一项,它永远指代新建的那个实例对象,Python语法要求这个参数必须要有,而名称随意,习惯上就命为self。
__init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__ init__.py 文件。
通常__init__.py 文件为空,但是我们还可以为它增加其他的功能。我们在导入一个包时,实际上是导入了它的__init__.py文件。这样我们可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入。
__init__.py中还有一个重要的变量,__all__, 它用来将模块全部导入。
# __init__.py
__all__ = ['os', 'sys', 're', 'urllib']
# a.py
from package import *
这时就会把注册在__init__.py文件中__all__列表中的模块和包导入到当前文件中来。
命名空间
- python使用命名空间记录变量。python中的命名空间就像是一个dict,key是变量的名字,value是变量的值。
- python中,每个函数都有一个自己的命名空间,叫做local namespace,它记录了函数的变量。
- python中,每个module有一个自己的命名空间,叫做global namespace,它记录了module的变量,包括 functions, classes 和其它imported modules,还有 module级别的 变量和常量。
- 还有一个build-in 命名空间,可以被任意模块访问,这个build-in命名空间中包含了build-in function 和 exceptions。
- 当python中的某段代码要访问一个变量x时,python会在所有的命名空间中寻找这个变量,查找的顺序为:
local namespace - 指的是当前函数或者当前类方法。如果在当前函数中找到了变量,停止搜索。
global namespace - 指的是当前的模块。如果在当前模块中找到了变量,停止搜索。
build-in namespace - 如果在之前两个namespace中都找不到变量x,python会假设x是build-in的函数或者变量。如果x不是内置函数或者变量,python会报错NameError。
拷贝
• 直接赋值:其实就是对象的引用(别名)。
• 浅拷贝(copy):拷贝父对象,不会拷贝对象的内部的子对象。
• 深拷贝(deepcopy): copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象。
解析:
1、b = a: 赋值引用,a 和 b 都指向同一个对象。
2、b = a.copy(): 浅拷贝, a 和 b 是一个独立的对象,但他们的子对象还是指向统一对象(是引用)。
b = copy.deepcopy(a): 深度拷贝, a 和 b 完全拷贝了父对象及其子对象,两者是完全独立的。
Import 模块
-
Import 模块:
- import time 指 import time 模块;
- 方法二:import time as __,__下划线缩写部分可以自己定义,在代码中把time 定义成 t;
- 方法三:from time import time,localtime ,只import自己想要的功能;
- 方法四:from time import * 输入模块的所有功能。
可以被import语句导入的对象是以下类型:
• 模块文件(.py文件)
• C或C++扩展(已编译为共享库或DLL文件)
• 包(包含多个模块)
• 内建模块(使用C编写并已链接到Python解释器中)导入包
多个相关联的模块组成一个包,以便于维护和使用,同时能有限的避免命名空间的冲突。一般来说,包的结构可以是这样的:
package
|- subpackage1
|- init.py
|- a.py
|- subpackage2
|- init.py
|- b.py
有以下几种导入方式:
import subpackage1.a # 将模块subpackage.a导入全局命名空间,例如访问a中属性时用subpackage1.a.attr
from subpackage1 import a # 将模块a导入全局命名空间,例如访问a中属性时用a.attr_a
from subpackage.a import attr_a # 将模块a的属性直接导入到命名空间中,例如访问a中属性时直接用attr_a
元类metaClass
元类就是用来创建类的“东西”。你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。好吧,元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解 为:
MyClass = MetaClass()
MyObject = MyClass()
你已经看到了type可以让你像这样做:
MyClass = type('MyClass', (), {})
lambda 表达式
python 使用 lambda 表达式来创建匿名函数
• lambda只是一个表达式,函数体比def简单很多
• lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去
• lambda函数拥有自己的名字空间,且不能访问自有参数列表之外或全局名字空间里的参数
• 虽然lambda函数看起来只能写一行,却不等同于C或C++的内联函数,后者的目的是调用小函数时不占用栈内存从而增加运行效率
lambda函数的语法只包含一个语句: lambda [arg1 [,arg2,.....argn]]:expression
使用如下:
1 square = lambda x : x**2
2 print(square(3)) # 9
3
4 sum = lambda x, y : x + y
5 print(sum(2, 3)) # 5
冒号左边→想要传递的参数
冒号右边→想要得到的数(可能带表达式)