本文主要分享下曾经让我非常头疼的有关python语法的三个知识点,这三点吧,放在那时候看,说掌握,谈不上,说不懂吧,感觉又能说一大堆。到了如今,应该是差不多理解到位了,所以分享分享
01 类的构造函数(__init__(self))
1) 构造函数(__init__)的理解
a) 构造函数用来初始化对象的状态,构造函数的任务是在创建类的对象时向类的数据成员(属性)提供初始化参数。
b) 与普通函数方法一样的是,构造函数内部也可以包含在创建对象过程中需要执行的函数,也就是说不仅仅只有属性
c) 实例化类对象会自动运行构造函数,所以你要声明所有可能你要用的属性,就算不是马上用,你也可以给先将变量赋值为None
2) 特殊参数self的理解
概念我相信很多人都说的上来,这是一个特殊变量,这个变量永远指向当前对象,但是当时我确实不太理解这个'当前对象'是个啥意思,后面随着敲代码敲多了,慢慢的也就明白了···(所以说学习的真谛还是得读书+实操)
下面我分成了3个层次的解释,越来越通俗的那种,希望不明白的你可以明白!
a) 初级解释
当你对一个类实例化,就要调用__init__(self)方法,这个方法的self参数就会存储当前这个实例的所有的初始化数据(不论需不需要其他参数,self变量都要有)
b) 中级解释
调用__init__(self)方法,根据你传入的不同参数构建不同的实例,每个self分别代表着带有不同参数的实例对象**
c) 终极解释
举个例子:比如我们要构造Person类,那人与人之间肯定有不同的属性,比如身份证号,以及相同的属性,比如性别,姓名重复等等
假设说,我们这里只需要人名和身份证号来确定这个人是谁,那么也就是说我们的构造函数__init__(self, personal_id, name)大概应该是这样的,需要传入两个必须的参数name和personal_id
我们这里构造两个人,分别是小红和小陈,为了简单起见,假设他们的id分别是1和2,那么生成小红对象就是Person(1, "小红"),生成小陈对象就是Person(2, "小陈"),那么小红的self就是指小红这个实例,这个实例带有ID=1和name='小红'的属性,而小陈的self就是指小陈这个对象,同样带有ID=2和name='小陈'的属性
所以在这个Person类中的其他函数方法中带有的特殊self参数都是指带有两个属性的小红或者小陈,这两个属性在整个类中的任何包含self的方法都可以用.name或者.personal_id进行使用
d) 究极解释
如果还没看懂,上代码吧,我心也累了···
02 __init__.py文件的作用
我相信大伙都知道的是:__init__.py 文件是将文件夹变为一个Python模块,且有了__init__.py则可以被其他模块当作包来导入,至于__init__.py文件里面有没有内容无所谓,但是除了这些口头上可以说的,我们还应该真正的探究下这个文件是如何正确得理解和使用
1)当我们导入包到其他模块中,我们首先执行的是那个包的__init__.py文件中的内容,就和上面的实例方法类似,这个py文件自动执行,不论里面有什么
2) 既然先执行这个文件,那么这个文件一般会存放一些我们所需要的模块,因为这样,我们就不用重复的在其他模块导包
3) 这个文件中一般都会包含__all__变量,整个__all__就是用来限定外部的包可以使用当前包的哪些模块
4) 我个人另外还有个喜欢的用法就是将当前包的位置写入环境(但是一般都是在项目的顶级文件夹目录的__init__.py文件中添加路径,这样,整个项目都可以在环境中找到)
03 脚本中的if __name__ == '__main__'到底怎么理解
1) 概念解释
想当年,我刚开始接触到这个语法的时候,非常不理解这个语法到底的意义在哪里,但是还是按照这种写法去运行我的脚本文件···写着写着,也就通了,所以这里也回头来解释下
a) 首先你要知道,在代码正式执行前,python解释器会内部设置一些全局变量,基本都是双下划线方法
b) 其次,你要知道这些全局变量中有个__name__属性,而你启动程序总会有个入口文件(某个py文件),这个入口文件启动后,__name__就会赋值为__main__
c) 而程序运行中的其他module的每个py文件中的__name__会被赋值为所在模块相应的名字
总结来说,这个语句下面的代码块会被执行的唯一条件就是当前py文件作为程序的启动文件启动,只要不是作为启动文件,语句下面的代码就不会执行
2) 语句的意义
既然我们知道了只有当某个py文件作为启动文件才会执行这个语句下面的代码块,那么这个语句有什么意义呢?
在我看来,至少有两个意义
a)当作整套程序启动程序的入口,比如flask的启动就是很好的例子
b) 这里举例说明,假设你的启动文件是a.py,但是需要导入b.py中的函数或类,而b中所包含的函数或是类如果也需要单独的测试(跟专门的单元测试没有关系)或是其他功能的输出,就可以将测试或者单独的功能代码写在if __name__ == '__main__'的下面,这样,a模块导入b模块,就不会执行if __name__ == '__main__'下面的代码块。同样的,b如果需要完成上面所说的测试或是其他特殊功能,则应该直接运行b当作启动文件,这时,if __name__ == '__main__'下面的代码块就得以顺利执行。这样两个模块对各自的特殊功能就不会干扰
我是一名奋战在编程界的pythoner,工作中既要和数据打交道,也要和erp系统,web网站保持友好的沟通……,时不时的会分享一些提高效率的编程小技巧,在实际应用中遇到的问题以及解决方案,或者源码的阅读等等,欢迎大家一起来讨论!如果觉得写得还不错,欢迎关注点赞,谢谢。
领取专属 10元无门槛券
私享最新 技术干货