".py" 文件是标准的Python源代码文件;".ipynb"文件是使用 Jupyter Notebook(IPython notebook),类似于word文档的后缀,有.dox也有.docx。
__init__.py的作用是简化导入语句。
#main.py所在目录
|- main.py
|- my_module1.py
|- my_function1() # my_module.py中的一个函数
|- my_package # my_package是一个文件夹
|- __init__.py # 有或者没有"__init__.py",其内容为from .my_module2 import my_function2;点号"."定位到当前目录。
|- my_module2.py
|- my_function2()
没有__init__.py时,导入其他模块的函数,需要一层层地去找,所以导入语句长度也与文件夹层数成正比。如下目录想要在main.py中调用my_function1()和my_function2()时
from my_module1 import my_function1
from my_package.my_module2 import my_function2
有__init__.py时,导入函数my_function2()函数,就不用逐层深入地去找了,就可以用下面的语句导入了:
from my_module1 import my_function1
from my_package import my_function2
当我们导入my_package时,python会先看下这个文件夹下有没有__init__.py这个文件,如果有,就先执行这个文件,相当于初始化my_package,跟类(Class)首个方法__init__()作用差不多,都是初始化。于是乎,我们可以在刚导入my_package这个模块时,初始化加载my_function2到my_package中,在main.py里,我们就能用上面的语句导入my_function2了。
class类是模板,而实例则是根据类创建的对象
以圆为例,圆是具有圆周率(pi)和半径(r)两个相似特征的属性。根据相似特征抽象出圆类,而每个圆的圆周率pi是相同的,那么圆周率pi就可以作为类属性;每个圆的半径可以不同,那么半径可以作为圆的实例属性;一个实例可以计算面积(类作用),即为类的实例方法。而我们要知道圆的面积,周长等可以通过类方法计算出来。如下实例
class Circle(object):
pi = 3.14 # 类属性
def __init__(self, r): # 实例属性
self.r = r
def get_area(self): #实例方法:圆的面积
# return self.r**2 * Circle.pi # 通过实例修改pi的值对面积无影响,这个pi为类属性的值
return self.r**2 * self.pi # 通过实例修改pi的值对面积我们圆的面积就会改变
get_area(self) 就是一个方法,它的第一个参数是 self 。__init__(self, name)其实也可看做是一个特殊的实例方法。调用如下:
circle1 = Circle(1)
circle2 = Circle(2)
print('circle1.pi=\t', circle1.pi) # 3.14
print(circle2.get_area()) # 调用方法 self不需要传入参数,不要忘记方法后的括号 4*3.14
class的中子方法,self的作用
编写class的每一个子方法时,必须要用self,才能持续传递命名空间,也就是说只有用了self传递,才能调用子方法,这是一个python的内部寻址机制,叫做命名空间检索。通过利用自省工具dir(), print(dir(self)) , 打印出来self,可以看到完整的类命名空间里面都有些啥,也就是说其实写class的时候不传self,那你是得不到这些可操作对象的。
class Rectangle():
def getperi(self,a,b):
return (a+b)*2
def getarea(self,a,b):
return a*b
class RectangleInitSelf():
def __init__(self,a,b):
self.a=a
self.b=b
def getperi(self):
return(self.a+self.b)*2
def getarea(self):
return(self.a*self.b)
def Demoinit():
rect=Rectangle()
print(rect.getarea(3,4))
print(rect.getperi(3,4))
print(rect.__dict__)
def DemoinitInint():
rect=RectangleInitSelf(3,4)
print(rect.getarea())
print(rect.getperi())
print(rect.__dict__)
if __name__=="__main__":
Demoinit()
DemoinitInint()
显示结果:12 14 {}
12 14 {'a': 3, 'b': 4}
未定义init()时,我们通过print(rect.dict)来看这个实例的属性,竟然是空的,我定义了一个矩形,按理来说它的属性应该是它的长、宽;在实例化对象的时候,rect = Rectangle()参数为空,没有指定a、b的值,只有在调用函数的时候才指定了。且类中定义的每个方法的参数都有a、b,这显然浪费感情,在类中直接指定方法就可以了。当定义完init()后,创建的每个实例都有自己的属性,也方便直接调用类中的函数;同时方便创建实例的时候,需要给实例绑定上属性,也方便类中的方法(函数)的定义。