我们都知道,在算法中有些问题的计算具有规律性,比如计算x的平方,x的三次方,x的n次方......当我们用Python函数来编程实现相关的算法时,你会发现计算x的平方的函数不能实现对x的三次方的计算,需要另外重新定义一个计算立方的函数。因此,看似简单的参数调用背后却有着深奥的知识,掌握各种参数的类型不仅能简化代码,事半功倍,还能展现出更强大的逻辑思维。
参数类型:
1.位置参数
调用函数时按照x和n的位置依次将x的值3和n的值4传入函数意味着计算x的n次方
2.默认参数
当默认n为2时函数可只传入非默认参数x的值即默认计算x的平方,也可传入x的值和非2的n的值来改变默认参数n来计算x的n次方
注:默认参数只能指向不变对象
3.可变参数
4.关键字参数
**表示将kw包装为dict传入函数,此时传参即为键值对,如果要限制传入参数的个数,那么
同时,一个函数中若有两个参数,那么这两个参数都可以包装成元组和字典进行组合传入
1.序列的概念
序列是指内容连续,有序,可使用下表索引的一类数据容器。数据容器如列表,元组,字符串均可视为序列。
2.序列的切片
语法:序列[起始下标:结束下标:步长]
注:切片操作不会影响序列本身,而是得到一个新序列,并且新序列的类型和原序列一样
无论是任何数据容器,在Python中都可使用for循环进行元素的迭代
1.列表和元组的迭代
2.dict字典的迭代
3.如何判断一个对象是否可以迭代
使用isinstance函数判断
如果要实现下标形式的键值对则可以如下图所示
我们都知道,在创建多个函数的时候有些函数中的方法有重复,如果在每个函数中一个一个去写又会显得代码十分冗余,那么Python便给出了继承这一功能.通过继承不仅可以使子类使用父类中的属性和方法,还能强化代码的逻辑性.
1.单继承
在类personal_Student这个类中继承了父类的成员变量a和方法_self_information,当然也可以用isinstance方法查看b与父类之间的关系,但是要注意,必须要创建一个实例对象才可使用
2.多继承
在Python中类和类之间也允许多继承,即一个类允许继承多个类,同样,这个子类也可以调用所继承的父类中的属性和方法,但是若父类中有相同方法或者属性时子类在调用时会根据继承顺序来调用
当然,多重继承还可以通过另外一种方式实现:
不同的继承方式有着不同的逻辑关系,但是他们的目的都只有一个:简化代码,强化逻辑
异常的捕获
在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。
当try语块内的代码出现异常时,可以用except来索引该异常,代码会自动跳入执行except语块,如果except后还有finally,则会继续执行finally语块,特别注意的是:finally语块无论是否执行except最后都会被执行
当程序中有多个异常时也可以使用多个except语块来执行相关语句
如果try语块内的代码没有异常出现,则可以使用else语块来执行相关代码,并且如果最后有finally语块也会执行finally内的代码
调试:
程序能一次写完并正常运行的概率很小,基本不超过1%。总会有各种各样的bug需要修正。有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是正确的,哪些变量的值是错误的,因此,需要一整套调试程序的手段来修复bug。
这里引出“断言”的概念:
凡是用print()来辅助查看的地方,都可以用断言(assert)来替代:
assert的意思是,表达式n != 0应该是True,否则,根据程序运行的逻辑,后面的代码肯定会出错。
如果断言失败,assert语句本身就会抛出AssertionError
1.StringIO
很多时候,数据读写不一定是文件,也可以在内存中读写。
StringIO顾名思义就是在内存中读写str。
要把str写入StringIO,我们需要先创建一个StringIO,然后,像文件一样写入即可:
使用getvalue()
方法用于获得写入后的str字符串
若要读取StringIO中的内容,则可以使用以下方法:
2.BytesIO
StringIO只能用于读字符串str,如果想要读取二进制类型的数据,则必须要使用BytesIO
操作文件和目录的函数一部分放在os
模块中,一部分放在os.path
模块中,这一点要注意一下。
查看当前目录的绝对路径:
在某个目录下创建一个新目录,首先把新目录的完整路径表示出来:
把两个路径合成一个时,不要直接拼字符串,而要通过os.path.join()
函数,这样可以正确处理不同操作系统的路径分隔符。
同样的道理,要拆分路径时,也不要直接去拆字符串,而要通过os.path.split()
函数,这样可以把一个路径拆分为两部分,后一部分总是最后级别的目录或文件名:
这些合并、拆分路径的函数并不要求目录和文件要真实存在,它们只对字符串进行操作。
os.path.splitext()
可以直接让你得到文件扩展名,很多时候非常方便:
对文件重命名:
os.rename('原文件名','新文件名')
删掉文件:
os.remove('文件名')
我们把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling.
序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。
反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。
PICKLE
Python提供了pickle
模块来实现序列化。
当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes
,然后用pickle.loads()
方法反序列化出对象,也可以直接用pickle.load()
方法从一个file-like Object
中直接反序列化出对象。我们打开另一个Python命令行来反序列化刚才保存的对象:
JSON
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
Python内置的json
模块提供了非常完善的Python对象到JSON格式的转换。
dumps()
方法返回一个str
,内容就是标准的JSON。
要把JSON反序列化为Python对象,用loads()
或者对应的load()
方法,前者把JSON的字符串反序列化,后者从file-like Object
中读取字符串并反序列化:
1.datetime模块
如图所示我们可以导入datetime模块并且调用里面的datetime函数中的now方法用一个变量接收返回的当前时间.
再比如,用datetime模块还可以获取自定义的时间(如上图所示)
在计算机中,时间实际上是用数字表示的。我们把1970年1月1日 00:00:00 UTC+00:00时区的时刻称为epoch time,记为0
(1970年以前的时间timestamp为负数),当前时间就是相对于epoch time的秒数,称为timestamp。
datetime转换为timestamp
timestamp转换为datetime
datetime的加减:
2.collections模块
collections是Python内建的一个集合模块,提供了许多有用的集合类。
namedtuple
使用collections模块内的namedtuple函数可以表示一个事物的不同组成部分(如图表示用namedtuple函数表示二维平面一个坐标的x和y)
deque
使用list
存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list
是线性存储,数据量大的时候,插入和删除效率很低。
deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈
defaultdict
使用dict
时,如果引用的Key不存在,就会抛出KeyError
。如果希望key不存在时,返回一个默认值,就可以用defaultdict
:
OrderedDict
使用dict
时,Key是无序的。在对dict
做迭代时,我们无法确定Key的顺序。
如果要保持Key的顺序,可以用OrderedDict
:
注意,OrderedDict
的Key会按照插入的顺序排列,不是Key本身排序
ChainMap
ChainMap
可以把一组dict
串起来并组成一个逻辑上的dict
。ChainMap
本身也是一个dict,但是查找的时候,会按照顺序在内部的dict依次查找。
什么时候使用ChainMap
最合适?举个例子:应用程序往往都需要传入参数,参数可以通过命令行传入,可以通过环境变量传入,还可以有默认参数。我们可以用ChainMap
实现参数的优先级查找,即先查命令行参数,如果没有传入,再查环境变量,如果没有,就使用默认参数
通过对Python基础的学习,对编程语言中最至关重要的继承和多态有了很深的认识,可以说面向对象的根源就是继承与多态,封装。并且通过对数据容器的学习以及相应方法的学习加强了对数据的处理能力.