前言
对于计算机语言来说,不同语言其实区别并不是太大。我们在学习英语之后,常常会有着不同语言千差万别的刻板印象。但对于计算机语言来说,不同计算机语言的差别并不是想我们汉语和英语的差别那么大,用C语言能做的事情,用python也能做,区别仅仅在速度和性能不同罢了。
python是我学习的第一个计算机语言,作者本身目前才刚刚入门,难免出现片面的观点或者错误的看法,欢迎大佬们指正。
本章节仅仅是python的初阶知识,希望可以帮到读者学习并了解python。
一、python是什么?
与其说python是什么,不如说计算机语言是什么,不同计算机语言大同小类,都是一种计算机和人都能够识别的语言。其程序所使用的语句是用英文单词来表示,方便人们识别。
python在高级语言中属于面向对象的语言,功能十分强大,不依赖于具体机器,在任何型号的计算机中都适用。当然,计算机必须使用编译软件把python所编写的程序(也就是源程序)转换为计算机可以识别的机器指令(也就是目标程序),然后才能执行。
二、人们为什么使用python
关于这个问题,的确没有办法完全准确地回答这个问题。但是,对于python而言,它的优点决定了它的使用人数以及传播广度。
1、软件质量
? ? ? ? 在很大程度上,Python更注重可读性、一致性和软件质量,从而与脚本语言世界中的其他工具区别开来。Python代码的设计致力于可读性,因此具备了比传统脚本语言更优秀的可重用性和可维护性。即使代码并非你亲手所写,Python的一致性也保证了其代码易于理解。此外,Python支持软件开发的高级重用机制。例如面向对象程序设计(OOP,object-orientedprogramming)。
2、提高开发者的效率
? ? ? ? 相对于C、C++和Java等编译/静态类型语言,Python的开发者效率提高了数倍。Python代码的大小往往只有C++或Java代码的1/5~1/3。这就意味着可以录入更少的代码、调试更少的代码并在开发完成之后维护更少的代码。并且Python程序可以立即运行,无需传统编译/静态语言所必需的编译及链接等步骤,进一步提高了程序员的效率。
3、程序的可移植性
? ? ? ? 绝大多数的Python程序不做任何改变即可在所有主流计算机平台上运行。例如,在Linux和Windows之间移植Python代码,只需简单地在机器间复制代码即可。此外,Python提供了多种可选的独立程序,包括用户图形界面、数据库接入、基于Web的系统等。甚至包括程序启动和文件夹处理等操作系统接口,Python尽可能地考虑了程序的可移植性。
4、标准库的支持
? ? ? ? Python内置了众多预编译并可移植的功能模块,这些功能模块叫做标准库(standard library)。标准库支持一系列应用级的编程任务,涵盖了从字符模式到网络脚本编程的匹配等方面。此外,Python可通过自行开发的库或众多第三方的应用支持软件进行扩展。Python的第三方支持工具包括网站开发、数值计算、串口读写、游戏开发等各个方面。例如,NumPy是一个免费的、如同Matlab一样功能强大的数值计算开发平台。
5、组件集成
? ? ? ? Python脚本可通过灵活的集成机制轻松地与应用程序的其他部分进行通信。这种集成使Python成为产品定制和扩展的工具。如今,Python代码可以调用C和C++的库,可以被C和C++的程序调用,可以与Java组件集成,可以与COM和.NET等框架进行通信,并且可以通过SOAP、XML-RPC和CORBA等接口与网络进行交互。Python绝不仅仅是一个独立的工具。
6、享受乐趣
? ? ? ? Python的易用性和强大内置工具使编程成为一种乐趣而不是琐碎的重复劳动。尽管这是一个难以捉摸的优点,但这将对开发效率的提升有很重要的帮助。
? ? ? ? 以上因素中,对于绝大多数Python用户而言,前两项(质量和效率)也许是Python最具吸引力的两个优点。
三、开发环境
笔者习惯使用pycharm作为自身的python开发环境,但pycharm的购买费用较高,可以使用插件。(也就是在某宝购买激活码,几块钱的事情)
其余的开发环境如Visual Studio Code、Sublime Text、Jupyter Notebook以及线上开发环境,笔者用的并不多,这里不多陈述。
四、基础python知识
以下就是干货了,为了观看方便,我将字体改为微软雅黑了,祝你学习旅程愉快。
变量
变量名不能以数字开头,也不能以下划线开头,并区分大小写。
变量是什么,取决于最后一次赋值操作。这似乎与c语言等静态语言不同。
变量类型可以是字符串、数字、布尔值等等
序列(sequence)
1.不同变量之间进行分组,就是序列。所以序列是如同容器一般的储存变量的工具。其分为两种:列表(list)和元组(tuple)。
两者的区别在于:元组内的变量无法被改变,故也被称为定值表;而列表内的变量可以被改变。
构建方式如下:
①
example_tuple = (2, 1.3, "love", 5.6, 9, 12, False)? # 一个元组
example_list= [True, 5, "smile"]? ? ? ? ? ? ? ? ? # 一个列表
type(example_tuple)????????????????????????????????? # 结果为'tuple'
type(example_list)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 结果为'list'
②
number = [1,2,3,4,5,]
type(number)
for each in number:
? print(each)
2.用letters读取list中的变量。
如
并且list中的变量可以被修改
如
补充①用remove函数可以直接删除元素。(如果有多个元素则只删除下标最小的元素)
②pop()函数会取出并删除指定元素,它的参数是一个索引值。如果不带参数,pop函数会默认最后一个元素。Pop(弹出)函数的作用与其说是删除,不如说是取出顶部的函数于一个新的列表之中。
3.增加与替换
也可以使用append与extend进行添加元素,不过append一次只能添加一个元素。
而extend可以一次添加多个元素,并与append一样保存于原序列的最后一个元素的后面。
两者的区别:append直接以列表的形式插入列表,而extend以元素的形式添加入列表。
Insert提供索引。
还有:
注意这里的s[len(s):]中的len(s):指的是下标。
认识到在list中,字符串每个变量均有从0开始的下标(也可以从最后一个元素为-1开始,倒数第二个为-2,类推……),如list = [1、2、3、4],1对应的下标为o,以此类推。即:在list.insert中(1、”orange”)是在原list中的apple后加上orange。
有与reverse和sort共用的效果,reverse默认为false。效果颠倒
标注:[3:]指的是下标3之后的所以元素。
4:索引
使用index函数直接索引就好。(index(x,start.end))
5:其他函数
如图:sort为自动排序原函数;reverse为将原函数顺序倒过来。
附加:copy拷贝整个序列。
Len即数列的数目(列长)
6.切片
这里有一个新的概念,即切片(slice)语法。如:从一个列表中取出最后的200个元素:
稍加繁琐。
使用切片的话,只需要输入范围就好。
列表切片可以接受第三个参数,其代表为步长,默认为1。
如>>>list1 = [1,2,3,4,5,6,7]
>>>list1[0:7:2]
[1,3,5,7]? ? ? 注:此中list1[0:7:2]可以表示成list1[::2]
7:拷贝
有浅拷贝与深拷贝之分。首先有一个引用的概念,如:
y与x一起被修改。
浅拷贝:如下图,有copy语法和切片语法可以达到效果。
其方法无法用于嵌套列表之中。
深拷贝:
字典
字典有许多以逗号隔开的元素组成,其中元素包含两部分:值(value)与键(key)。键是数据的索引,值是数据本身,两者一一对应。所以,字典中的值可以用键来引用:
example_dict = {"tom":11, "sam":57,"lily":100}
type(example_dict)? ? ? ? # 结果为'dict'
修改或增添时:
example_dict["tom"]? = 30
example_dict["lilei"] = 99
example_dict?
#结果为{"tom": 30, "lily": 100, "lilei": 99, "sam": 57
Clear方法,可以直接清空字典。
Update方法,可以合并两个字典。
元组
1.更新与删除
元组中元素不允许删除或更新,但可以创建一个新的同名元组。
图中“x教授”被替换成“小甲鱼”,x_men[2:]大概指从下标2开始的元素加原本的下标0对应的元素和新加元素。(狸猫换太子?)
元组虽然更新,但是新元组与原元组并不是同一个元组。如:
Id()函数是用于返回指定对象的唯一id值。在python中,每个对象的id值的是唯一的,以上两个元组虽然名称一样,但是id不同,在证明了它们并不是同一个元组。
删除:因为元组的不可删除性,删除其中元素的操作在理论是不可能。但是可以通过与之前一样的重名替换的操作,进行假删除。
删除只需使用del语句。但是日常不常使用,因为python的垃圾回收机制会在某个对象不再被使用时自动清理。
总结:1.有拼接操作符、重复操作符、关系操作符、逻辑操作符、成员关系操作符可以直接应用于元组上。
2.元组的标识符号是中括号(),列表的标识符号是[ ]。
语句
1、断言(assert)
一般在检测程序bug时使用。
while语句
While函数判断条件是否正确,如果正确,则继续运行;如果不正确,则停止。
prompt = "\nTell me something, and I will repeat it back to you:"
prompt += "\nEnter 'quit' to end the program. "
message = ""
while message != 'q':
? ? ? message = input(prompt)
与if语句的不同的是,只要条件为真,while语句会一直执行同一段代码。如:
注意:while语句可能会造成死循环,但死循环在游戏开发、服务器运行等的地方是非常必要的。
使用标志:标志是一个任意变量,在判断条件过多时,将判断条件赋予标志变量,判断标志变量是true还是false。当判断是true时,继续运行;判断是false时,结束运行。
3.分支与循环
If语法:判断一个条件,如果这个条件成立,就执行其包含的语句或板块。如:if condition
? ? ? ? ? ? ? statement(s)
如果不成立,则执行另一条语句或板块。即:else condition
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? statement(s)
? ? 如果都不成立,则执行特殊的语句或板块
2.嵌套:即s = [[1,2,3],[4,5,6],[7,8,9]]
3:死循环:ctrl+c强行结束运行
4(一):for循环:语法为---for+变量+in+集合:(for+变量+in+可迭代对象)
? ? ? ? ? ? ? 代码1
? ? ? ? ? ? ? 代码2
? ? ? ? ? ? ? ……如:
for i in range(1,10):
? ? ? Print(“i=%d”%(i))
#结果为:1,2,3,4……9
4(二):最基本的for循环是将其中对象中元素提取存放。
range用法:BIF函数,语法如下:
range(stop)
? ? ? range(start,stop)
? ? ? range(start,stop,step)
注意:range函数的参数只能是整数。
第一种:只有一种参数
简单明了,生成从0到该参数的数学序列。
第二种:指定了开始和结束的数值。
结果中有开始数值,但没有结束数值。
第三种:又规定了步长,不规定的话,步长默认是1。
如:
(步长无论正负)
break语句
break 语句是阻止死循环的有力手段,其作用是终止当前循环,跳出循体。
一个有点小意思的代码:
continue语句
此语句也可跳出循环,但会直接执行下一个循环。
为程序实现结果。
但是当使用else语句和break语句时,情况就有所特殊。
break直接跳过循环,else语句无法被执行。
字符串
附图:
查找和修改字符串
①count(sub[,start[,end]])方法用于查找sub参数在字符串中出现的次数。如
(其中count查找了“上”字于其中出现的次数。)
②find(sub[,start[,end]])或index(sub[,start[,end]]) 用于查找sub函数在字符串中第一次出现的位置,如果找到,返回索引值;如果找不到,find()返回-1,index()会显示异常。
③replace(old,new[,count])用于将指定的old参数替换成new参数。
④split(sep=None,maxsplit=-1)用于拆分字符串。
⑤join参数用于拼接字符串。
格式化:字符串格式化是为了统一。
①format()方法可以接收位置参数和关键字参数,两者均传递了一个名为replacement(用大括号{}表示)的字段。
位置参数即“a=x”的形式:关键字参数即下标。注意:位置参数必须位于关键字参数之前,否则就会出错。
这里{1}略有不同,f的意思是浮点数,“.2”的意思是四舍五入到保留两个小数点。
使用语法:“……{占位符}……”.format(variable)
占位输出
基本占位符替换,顺序替换
占位符位置数字输出
占位符关键字输出(传入键名)
占位符索引/键名输出(引用索引/键名)
占位符引用对象属性输出(类属性)
占位符语法:{【索引】【:【填充】【符号】【#】【字符串】【小数位】【数据类型】】}
但python3.10好像不能用。
②格式化操作符:%
当%符号两边都是数字时,该符号的意思是求余数。但当它出现在字符中的时候,则为格式化操作符。
格式化的含义是直接替换对应的对象。
Name = (“小米”)
Print(“我的名字叫:%s”+%name)
//%06
类和实例
在面向对象的编程之中,最重要的就是类和实例的概念。而类是一个抽象的模板,实例就是一个具体的对象。
方法
(以下方法特指内置方法)
(一)、__init__方法,自带,用于定义类属性。类属性(如self.age=age)与用=相连的对应关系(如age = 1)不同。? 定义类属性实际上是像定义字典中的一个变量,定义的是形参,实例化时输入传递的是实参。
1.触发时机:实例化对象之后触发
2.作用:为对象添加对象的所属成员
3.参数:一个self接受当前对象,其他的参数根据实例化的传参决定
4.返回值:无
5.注意事项:无
注:实例化对象时,实际进行了两边操作,第一,制作一个对象;第二,为对象初始化操作。
(二)、__new__方法
当实例化一个对象时,其内置的__new__方法会被自动调用,而手写__new__方法时,实际上是重载object内部自带的__new__方法
1.触发时机:在实例化对象时触发
2.作用:管理控制对象的生成过程
3.参数:一个cls接受当前类,其他的参数根据实例化的参数决定
4.返回值:可有可无,没有返回值时,实例化结果为none
5.注意事项:new魔术方法跟init的魔术方法的参数一致(除了第一个)
(三)、__del__方法
1.触发时机:对象被系统回收时触发
2.作用:回收程序使用过程的信息和变量等
3.参数:一个self接受当前对象
4.返回值:无
5.注意事项:无
在类创建好之后,可以把我们认为必须绑定的属性强制填写进去,用到了__init__的方法。
class Student(object):
? ? def __init__(self, name, score):
? ? ? ? self.name = name
? ? ? ? self.score = score
这里__init__函数的第一参数一定是self,表示创建的类实例本身。因此,在__init__函数内部,把各种属性传递绑定给self,因为,self就是创建的实例本身。所以,在传递参数时,就不能传入空的参数,必须与__init__方法相匹配的参数。
在定义一个类并实例化一个对象后,实际上有两步操作,1.制作一个对象;2.为对象初始化操作。所以__init__方法是在实例化对象时被直接执行的,无需调用。
二、定义函数;
def square_sum(a,b):
? ? a = a**2
? ? b = b**2
? ? c = a + b
? ? return c
print("am I alive?")
【return还起到了中止函数和制定返回值的功能。】
Return之后的代码不会被执行
二:调用函数:python之中有许多内置函数,而要调用一个函数,需要知道该函数的名称和参数。
同时,函数名其实就是指向一个函数对象的引用,完全可以把函数名赋值给一个变量,相当于给这个函数起了一个“别名”。
如果已经把函数定义保存为…….py文件了,那么,可以在该文件的当前目录下启动python解释器,用(from? …….py? import 该函数)直接使用。
即直接使用impout导入函数,用模块名.变量/模块名.函数的形式使用。
四:参数检查
对函数进行检查,只允许整数和浮点数类型的参数。数据类型检查可以用内置函数isinstance()实现:
def my_abs(x):
? ? if not isinstance(x, (int, float)):
? ? ? ? raise TypeError('bad operand type')
? ? if x >= 0:
? ? ? ? return x
? ? else: return -x
添加参数检查后,如果传入错误的参数类型,函数就可以抛出一个自己设定的错误提示。
五:传递参数
包裹传参
应用:一般传递参数时需要指定参数的个数,而当不知道需要传递多少参数时,用包裹传参的方式将非常有用。
用法:定义函数时,将参数定义为一个元组或者列表。
def package_position(*all_arguments):
? ? print(type(all_arguments))
package_position(5,6,7,1,2,3)
解包裹(unpacking)
应用:解包裹允许我们把一个数据传递给函数,再自动分解为各个参数。用法:
def unpacking(albic)
? ? print(a,b,c)
? ? args = (1,2,3)
unpacking(*args)
#结果:1,2,3
六:缺省函数
定义一个函数时,可以给某个参数指定一个默认值,具有默认值的参数就叫作缺省参数。
七、类(class)
类具有三大特点:1、封装2、继承3、多态
1、首先,函数都是封装在类(class)之中的,在类之外函数可以随意访问。
class gun:
? ? def __init__(self,model):
? ? ? ? self.model = model
? ? ? ? self.bullet_count = 0
? ? def add_bullet(self,count):
? ? ? ? self.bullet_count += count
? ? def shoot(self):
? ? ? ? if self.bullet_count <= 0:
? ? ? ? ? ? print("myzidan")
? ? ? ? ? ? return
? ? ? ? self.bullet_count -=1
? ? ? ? print("%s? %s"%(self.model,self.bullet_count))
class soldier:
? ? def __init__(self,name):
? ? ? ? self.name = name
? ? ? ? self.gun = None
? ? def fire(self):
? ? ? ? if self.gun == None:
? ? ? ? ? ? print("%s没有枪"%self.name)
? ? ? ? ? ? return
? ? ? ? self.gun.add_bullet(50)
? ? ? ? self.gun.shoot()
ak47 = gun("ak47")
xuasnduo = soldier("许三多")
xuasnduo.gun = ak47
xuasnduo.fire()
print(xuasnduo)
在类和函数之中有一个self的概念,这是一个默认变量,在类中定义函数,其第一参数一定是类的本身实例变量self,并且调用时,不用传递该变量。(arge是可变参数,接收的是一个tuple;kw是关键字参数,其接收的是一个dict。)
? 二个下划线开头的变量名是特殊变量,可以直接访问,不是private变量,不能自定义两个下划线的实例变量名。
2、继承
分为单继承和多继承。
单继承:继承的主要作用是实现代码的重写,继承使得子类拥有父类的方法和属性。
在编写dog类的时候,我们并没有重写eat和drink两个方法。我们只需要在dog后面的括号中加上父类的名字即可
这是一种具有传递性的方法
继承中的方法重写
当父类中的方法并不能完成子类的需求时,就需要方法重写。
覆盖父类的方法
对父类的方法进行扩展
使用super().父类方法来调用父类方法的执行
多继承:
对于python来说,一个子类可以有多个父类。多继承的基本语法是比较简单的。
3、多态:
多态的概念源自继承,多态是指一类事物有多种形态,比如动物类。
多态性:多态性
注意事项与编程方法:
1:”””英文三个双引号表示多行注释,以两组引号之间的内容为添加注释的内容。
2:使用exit()可以直接将python关闭.
3:在python程序编写的过程中,只有前面代码正确,无论中间相隔多少行代码,都被记录着,并可以在之后加以利用。==与!=
While函数判断条件是否正确,如果正确,则继续运行;如果不正确,则停止。
4.异常处理:
对于程序运行时可能产生的错误,我们可以提前在程序中处理。其提高了程序的容错率。
目的:1.开始让程序中止前进行更多的操作,比如提供更多的错误信息
2.让程序在犯错后依然能运行下去。
方法:
try:
<语句>? ? ? ? #运行别的代码
except <名字>:
<语句>? ? ? ? #如果在try部份引发了'name'异常
except <名字>,<数据>:
<语句>? ? ? ? #如果引发了'name'异常,获得附加的数据
else:
<语句>? ? ? ? #如果没有异常发生
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
? 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句。
? 如果except语句也出现异常,异常就会被递交到上层的try,或者的出现的最上方,程序结束,并打印默认的出错信息。
? 如果try执行时没有异常,python将执行else后的语句(如果有else的话),然后控制流通过整个try语句。
举例:
whileTrue:
inputStr=input("Pleaseinputanumer:")#等待输入
try:
num=float(inputStr)
print("Inputnumber:",num)
print("result:",10/num)
exceptValueError:
print("Illegalinput.TryAgain.")
except(2):
print("Illegaldevisionbyzero.TryAgain.")
except Exception as num:
print(“未知错误%d”%num)
? ? ? ? ? ? else? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #没有异常才执行的代码
? ? ? ? ? ? ? ? ? pass
? ? ? ? ? ? finally? ? ? ? ? ? ? ? ? ? ? ? ? #无论有没有异常都会执行的代码
? ? ? ? ? ? ? ? ? pass
异常的传递性
5.单例方法:单例方法是__new__方法的经典应用,举个例子,我们电脑中只有一个回收站,在整个操作系统中,回收站只能有一个实例,整个系统都使用这个唯一的实例,而且回收站自行提供自己的实例。因此回收站是单例模式的应用。
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,单例模式是一种对象创建型模式。
例如:
目的:保证每一个类仅有一个实例,并为它提供一个全局访问点。
单例类(singleton)保证了程序中同一时刻最多存在该类的一个对象。
singleton模式的功能有两点:一是保证程序的正确性,使得最多存在一种实例的对象不会被多次创建。二是提高程序性能,避免了多余对象的创建从而降低了内存占用。
模块:
每一个以扩展名py结尾的python源代码都是一个模块,在模块中定义的全局变量、函数、类都是提供给外界直接使用的工具。
导入方式:
[1].import导入
在导入模块时,每个导入应该独占一行
Import 模块名1
Import 模块名2
导入之后,通过模块名.使用模块提供的工具---全局变量、函数、类
注:使用as指定模块的别名
如果模块的名字太长,可以使用as指定模块的名称,以方便在代码中的使用。
Import 模块名1 as 别名
[2].from……import导入
部分导入,导入之后,不需要调用,直接使用模块中的函数、变量
注意,如果同时导入两个模块的同名函数,后导入的函数将覆盖前导入的函数。当有同名函数的情况发生时,可以使用as给被导入函数起一个别名。
注意事项? (1)、在给模块名起名时,不能与系统的模块文件重名,python导入模块时,会先搜索当前目录,如果没有,才会搜索系统目录。
python中每一个模块都有一个内置属性__file__可以查看模块的完整路径。
(2)、在导入模块时,被导入模块之中的未被缩减的代码均会被执行。
例如:被导入模块中有print("111")
未被缩减,导入模块时就会被直接执行。
__name__属性:其作用是在测试模块的代码只在测试情况下被运行,而被导入时不会被执行。
其执行:1、如果直接执行模块,__name__的结果是__main__
即:print(__name__)输入__main__.
2、使用方法
If __name__ =="__main__":
? ? print("11")
? ? print("@@")
在使用if语句时,被导入模块的代码都没有被执行。
3、使用场景:
Def main():
……
Pass
…………………………
If __name__ =="__main__"
? ? main()
在实际开发时,以上代码普遍存在,用于只在测试情况下被运行。
那如果是 if 1=1呢?
包:
包是一个包含多个模块的特殊目录,目录下有一个特殊的文件__init__.py
作用:使用import可以一次性导入包中的所有的模块。
__init__.py:要在外界使用包中的模块,需要在__init__.py中指定对外界提供的模块列表。
from? . Import + 被导入模块
6、方法
open函数负责打开文件,并且返回文件对象
Read/write/close三个方法都需要通过文件对象来调用。
open函数的第一个参数就是要打开的文件名(如果文件存在,返回文件操作对象)
read方法可以一次性读入并返回文件的所有内容
close方法负责关闭文件(如果忘记文件关闭,会造成系统资源消耗,而且会影响到后续对文件的访问。)
注意事项:文件指针
1、文件指针是标记从哪个位置开始读取数据
2、第一次打开文件时,通常文件指针会指向文件的开始位置
3、当执行了read方法后,文件指针会移动到读取内容的末尾。因此不会执行最后一行代码以上的代码。
五、总结
关于这次文章,我也算写了很长时间,有两个月了吧。断断停停,终于写完了。当然,学习完这些知识不过刚刚入门,之后还有很长的路要走。