准备
python有两个版本Python2 python3,目前社会包括公司主要是用pyhton2,但是python2官方将在2020年停止支持,所以用python3吧,python和python的差别不大,我们学会了python3,是能够看懂python2代码的。
python是一种脚本语言,一般以.py后缀结尾的文本文件,python同样也是一门解释型语言,也就是说他一条一条的解释成机器语言再来执行,这就导致python语言在执行的时候会比C、java这类编译型语言慢的原因,编译型语言更偏向于机器能够读懂,但有好处,就是python更加倾向于人能读懂的语言,python这门语言十分简洁,
假定你有一定的计算机语言基础,各大计算机语言(C、C++、java)其实一通百通,
为何python近几年这么火?还不是因为人工智能的兴起,硬件技术的提升,使得之前深度学习的复杂算法得以实现,能够得到更大识别率,OK不扯远了,Python强大在何处?它有非常庞大和丰富的库,使得我们写起代码来非常轻松,原本用C下3天才能实现的功能,用python一天就能实现
一般我们如何运行python代码,要运行python代码我们首先要安装python的运行环境,一般我们安装anaconda而不是直接安装python,因为anaconda直接帮我们安装好了很多数据科学的库,并且什么运行环境在安装的时候就帮我们设置好了,还有很多好处,不一一解释了。
设置好了运行环境,仅仅只是意味着我们的电脑可以运行python代码而已,我们在以前学C原因的是候都会安装一个叫做IDE(集成开发环境)例如VC++,那么我在这里说一声python安不安装IDE都无所谓,如果大家想安装的话我推荐pycharm,这个是写python代码最好的IDE,当然其他的都行,
为什么我说安不安装都行呢,因为IDE很大,很笨重,但是写大型项目的时候很方便,方便调试,不扯了,会回归这题,我们该如何写python代码,我的答案是,什么都可以写,任何一个文本编辑器都可以写
首推sublime(写出的代码非常漂亮,并且在文本编辑器中就可以运行简单的代码),但是收费,不过能够永久免费的使用。
Jupyter Notebook (anaconda自带的编辑器,轻巧,代码可以一部分一部分的执行,方便看到每部分执行后的结果,特别是对那些几百行几千行的代码)
notepad++
EditPlus
可以再交互式环境中直接编写 print("Hello World")
python入门
python是一门强类型语言,给变量赋值前不需要给定变量的数据类型,变量的数据类型在赋值的时候就被给定。
var1 = 1 var2 = "hello world" var4 = 'hello world' var3 = 3.3
input():从键盘获取输入,
x = input("请输入一个数字:")
X是字符串的数据类型
print():打印,
print("hello"+'world')
+号,字符串的拼接符,如果想拼接数字,需要str(number),强制数据类型转换
单行注释 #
多行注释 三个引号,一般用来作文档说明,函数、类、模块的用法说明
1 # 注释1 2 # 注释2 3 4 """ 注释3 """ 5 ''' 注释4 ''' 6 7 # 多行注释 8 """ 9 第一行 10 第二行 11 第三行 12 """
Python的一大特点,交叉赋值,也就是交换两个变量的值,在C语言中交换,需要引入第三个变量
赋值:将对象绑定到名字上 =
双等号 == ,用来做判断是否相等
a = 1 b = 2 a,b = b,a # 交叉赋值 print("a的值为:",a) # a的值为: 2 print("b的值为:",b) # b的值为: 1 print("a是否等于b:",a==b) # a是否等于b False
基本函数
is / is not 判断两个对象是否是同一个对象,如果是返回True,否则返回False
in / not in 判断字符串是否在,返回True or False
print(1,2,3,end="/n") end:在输入完毕后在末尾自动追加一个字符串,print()中默认end=('/n')所以print函数会换行,我们用end=' '可以让结果的结尾避免换行,通常用来避免不同print之间的换行。
print(1,2,3,sep='*') sep:分隔号*,往可迭代对象中插入分隔符
id(obj) 返回一个对象在内存中的地址
del 变量名 删除变量,删除变量和内存的绑定关系,释放内存
len(x) 返回X的长度
abs(x) 返回X的绝对值
pass 空语句,没有任何作意义,但是却有很大的作用,可以让一个函数占位,不会报错。
1 def hello(): 2 pass 3 4 def world(): 5 print("world") 6 7 hello() 8 world()
None, 空值,运算符 + - * / %求余 //地板除 取整 **取指数
1 print(5/2) # 2.5 2 print(5//2) # 2 3 print(5%2) # 1
round(number, ndigits=0) 对number进行四舍五入,ndigits是小数点向右取整的位数,负数表示先左取整的位数
pow(x,t,z) # x**y%z
%占位符 print("我叫%s,年龄%d"%("LXP-Never",23))
讲几个重要的字符串的方法
'+'.join('1234') 将字符串'+'插入含字符串的可迭代对象(列表、元组、字符串),返回字符串 1+2+3+4
'1+2+3+4'.split('+') 将字符串按指定字符拆分,返回列表 ['1', '2', '3', '4']
S.count(sub[, start[,end]]) 获取一个字符在字符串中的个数
S.find(sub[, start[,end]]) 获取字符串中子串sub的索引,失败返回-1
S.index(sub) 返回一个字符在字符串中的索引,若没有,会报一个异常
S.strip() 返回去掉左右空白字符的字符串
range() 用来生成一系列整数的可迭代对象,(整数序列生成器)range函数的返回值可用于for语句来一次迭代输出整数,生成的是数字序列,range(start,stop) 从start开始,到stop,但是不包括stop,可以取步长
1 num1 = range(5) 2 num2 = range(1,8,2) 3 lis = list(num1) 4 print(num1) # range(0, 5) 因为range()是一个生成器 5 print(lis) # [0, 1, 2, 3, 4] 6 print(list(num2)) # [1, 3, 5, 7]
列表
[1,2,3,["nihao"],"hello"] # 列表可以嵌套列表,同时也可以嵌套其他的容器(元组、字典、集合)
列表是python容器之一,列表是可迭代对象,
list() # 创建一个空列表
list(可迭代对象) # 将可迭代对象创建为列表类型
废话不多说,我们先来创建一个列表,
lis1 = list('nihao') # 将字符串'nihao'创建为列表 lis2 = list() # 创建空列表 lis3 = [] # 创建空列表 print(lis1) # ['n', 'i', 'h', 'a', 'o'] print(lis2) # [] print(lis3) # []
基本函数len(L)返回列表的长度,max(x)返回序列的最大值,min(x),sum(x),
列表的一些重要方法:
L.append(x) # 在列表的最后插入元素x
L.sort(reverse=False) # 将列表中的元素从大到小排序
sort(L) # 返回排序后的对象
L.reverse() # 将列表反转
L.insex(v[,begin[,end]]) # 返回对应元素v的索引下标
L.insert(index,obj) # 将obj元素插入到列表的指定位置
L.remove(x)
L.pop(index) # 返回删除的元素
列表推导式
语法:[表达式 for 变量 in 可迭代对象]
或 [表达式 for 变量 in 可迭代对象 if 真值表达式]
# 生成一个数值为 1 ~ 9 的平方的列表 L = [x**2 for x in range(1, 10)] print(L) #[1, 4, 9, 16, 25, 36, 49, 64, 81] L = [x for x in range(1, 10) if x % 2 == 1] print(L) #[1, 3, 5, 7, 9]
元组
元组是不可修改的有序序列,元组使用小括号(),列表使用综括号[]
元组只含一个元素时,需要在后面添加逗号,否者会被当做变量来处理
括号可以省略
元组可以通过索引下标访问里面的元素,也可以通过切片访问
元组的值不能删除,也不能向元组中添加值,
tuple2 = (1,2,'wo',4,5) print(tuple2) # (1, 2, 'wo', 4, 5) tuple3 = "wo","ai","ni" # 不需要括号也可以 print(tuple3) # ('wo', 'ai', 'ni') print(type(tuple3)) # <class 'tuple'>类型为元组类型 tup1 = () #() print(tup1) tup2 = (50) # 不加逗号,类型为整型 print(tup2) #50, tup3 = (50,) # 加逗号,类型为元组 print(tup3) #(50,)
元组没有推导式
字典
字典是可修改的无序序列,字典使用花括号{}
字典由键值对组成{key:value}
键在字典中是唯一的,如果重复,后面的键值对会替换前面的。
键必须是不可变的类型对象,只能用数字、字符串、元组充当,列表就不行,值可以是任意数据类型
当键不存在时,创建键,并绑定对应的值,当键存在时,修改键绑定的值
# 创建字典dict dict1 = {'a':2,'b':1,'b':3} # 重复最后的一个键值对会替换前面的,值不需要唯一 print(dict1) # {'a': 2, 'b': 3} dict1['c'] = 4 # 当键不存在时,增加键,并绑定对应的值, print(dict1) # {'a': 2, 'b': 3, 'c': 4} dict1['c'] = 134 # 当键存在时,修改键绑定的值 print(dict1) # {'a': 2, 'b': 3, 'c': 134}
字典推导式: {x:x**2 for x in range(10)}返回字典
集合
集合是可修改的无序的不可重复的序列,集合使用花括号{}
s = set([3,4,6,6,7]) #创建一个数字集合 t = set("hello")# 遍历字符串中的每个字符,拆开成单个字符 print("s:",s) # s: {3, 4, 5, 6, 7} print("t:",t) # w: {2, 3, 4}
s = set([3,4,5,6,7]) #创建一个数字集合{3, 4, 5, 6, 7} w = set([2,3,4]) print("求交集:",s&w) # {3, 4} print("求并集:",s | w) # {2, 3, 4, 5, 6, 7} print("求差集:",s-w) # 减去相同的元素 {5, 6, 7} print("求差集:",w-s) # 减去相同的元素 {2} print("并集减去交集:",s ^ w) # {2, 5, 6, 7}
集合推导式
{表达式 for 变量 in 可迭代对象 [if 真值表达式]} # [ ]可以省略
{x for x in range(10)} # 返回集合
可迭代对象的切片操作
列表的切片操作
只要是可迭代对象,都可以进行切片
字符串序列[(开始索引a):(结束索引b)(:(步长s))] #不包括结束索引b,python中的序列索引下标是从0开始的,和MATLAB有所不同,C语言也是从0开始的。
str = "hello world" slice = str[0:6:2] print("str[0:6:2]:",slice) # hlo
可以改变列表的排序,可以插入和修改数据。可以用切片改变对应元素的值
函数
为什么要用函数呢,我们需要某个功能的时候,在主函数中设计不就行了吗,当然这样是可行的,但是如果我们的主函数需要很多次这个功能,那我们是不是要一直设计,粘贴复制我们的代码呢,这样就导致我们的代码阅读起来比较困难,而且重复代码过多,失去了代码的简洁性。这时候,函数就起到了作用,函数是可重复性质的语句块,可以重复调用。
python语言中不需要begin/end或者{}来表示语句的范围,代码块之间直接通过缩进来指示
Python不需要语句终止符;
python语言的特色,函数可以返回多个值(以元组的形式),当没有返回值的时候自动返回None
我们需要注意全局变量和局部变量的问题,在函数内能同时访问局部变量和全局变量,在函数外只能访问全局变量。
不能使用关键字做变量名或者函数名,
既然讲到函数,那么就不得不讲到函数的传参和形参
形参
什么是形参?形参就是我们定义函数时,后跟要求输入的参数
语法:def 函数名(形参名=默认实参1,形参2=默认实参2,…)
形参一共有这么几种类型
位置形参
按照形参的位置,
def 函数名(形参名1,形参名2,…)
语句块
星号元组形参
一般用来接收多于的位置传参,如果传入的是关键字是接收不了的
def 函数名(*元组形参名)
语句块
命名关键字形参
def fa(a, b): print('a=', a) print('b=', b) def fb(*args, a, b): print("args=", args) print('a=', a) print('b=', b) fa(b=2, a=1) print("#########################") fa(**{'b': 2, 'a': 1}) print("#########################") fb(1, 2, 3, 4, b=2, a=1)
双星号关键字形参
用来接收多余的关键字
def 函数名(**字典形参名)
语句块
传参
传参一共有这么几种类型
位置传参
实参和形参的位置必须一一对应
序列传参
用*,*后面跟着可迭代序列,序列拆解的位置与形参一一对应
def myfun1(a,b,c): print('a的值是:', a) print('b的值是:', b) print('c的值是:',c) myfun1(*[11,22,33]) #相当于myfun1(11,22,33) myfun1(s1[0],s1[1],s1[2])
关键字传参
按形参的名字给形参赋值,实参名必须与形参名进行匹配
字典关键字传参
实参为字典,将字典用’**’,拆解后在进行关键字传参的传参方式
def myfun1(a, b, c): # 这是一个函数的传参示例,此函数以后不会改变代码 print('a 的值是:', a) print('b 的值是:', b) print('c 的值是:', c) d = {'a': 100, 'b': 200, 'c': 300} myfun1(**d) # 等同于 myfun1(a=100,b=200,c=300)
还有一个重要函数,那么就是
匿名函数
lambda [参数1,参数2...]:表达式
举个栗子
myadd = lambda x,y:x+y
注意:
lambda表达式只能包含一条语句,用来创建一个函数的对象。
补充:
函数的文档字符串,就是在开始写函数的时候,用字符串来说明该函数用来做什么的。
函数内第一次未被赋值给任何变量得字符串是此函数的文档字符串
def 函数名(参数列表):
'函数文档字符串'
函数语句块
>>>help(函数名) # 可以用来查看函数的帮助文档
使用函数时,应该尽量避免使用全局变量,尽量用函数传参来传递全局变量,这样可以避免多个模块文件跨包取值。
def fun(): "这是一段文档字符串" pass print(fun.__doc__) # 这是一段文档字符串 print(help(fun)) # Help on function fun in module __main__: # fun() # 这是一段文档字符串 # None
那么函数也差不多讲完了,另外请务必记住全局变量和局部变量之间的区别。当然在全局区域还是有方法调用局部变量的,这个问题笔者就抛出来,交给读者去探索。
模块
模块,模块是什么?我想这也是我们大家见到这个词的第一个问题。OK,既然你们诚心诚意的发问了,那么我就大发慈悲的告诉你,模块可以理解为一个.py脚本文件,这个脚本文件中定义了很多变量、写了很多函数和类。
python有四大模块:
内建模块(math、time、random、sys)、标准模块、第三方模块、用户自定义模块
引用模块:
import module,module...
from ...import ...
from ... import * # 把一个模块中的内容全部导入到当前命名空间,一般不建议......
使用模块函数
模块名.函数名()
模块名.变量名()
模块名.类名.函数名()
举个栗子:
math.ceil(x) # 对x向上取整
math.floor(x) # 对x向下取整
time.sleep(x) # 让程序睡眠x秒
给大家讲一个比较常用的,系统模块 sys
sys.path # 搜索当前脚本文件的路径
sys.argv # 返回命令行第一个参数 python temp.py
random.random() # 返回一个[0,1)之间的随机数
模块包
包就是文件夹,包文件夹必须存在__init__.py。通常用来放这个包的文档字符串,该文件的内容可以为空__int__用于标识当前文件夹是一个包,__init__会在包加载时自动调用
包的导入
#import 语句
import 包名 [as 包新名]
import 包名.模块名 [as 模块新名]
import 包名.子包名.模块名 [as 模块新名]
#from import语句
from 包名 import 模块名 [as 模块新名]
from 包名.子包名 import 模块名 [as 模块新名]
from 包名.子包名.模块名 import 属性名 [as 属性新名]
from 模块名 import 函数名 (不用写模块名.函数名)
# from import *语句
from 模块名 import* (不用写模块名.函数名)
from 包名 import *
from 包名.模块名 import *
导入包时,默然先搜索程序的当前路径,如果没找到,然后搜索sys.path提供的路径,如果还是没有,那么python会查看默认的路径,也就是环境变量。
__init__.py内的__all__列表
作用:用来记录此包中有哪些子包或者模块在用from import* 语句时被导用
说明:__all__列表只对 from xxx import *语句起作用
相对路径和绝对路径大家能够分的清楚吧,
在模块导入时,模块的所有语句都会执行一边,如果再次导入模块,那么模块不会再次执行。
模块的预置属性
模块的__doc__属性绑定模块的文档字符串
模块的__file__属性绑定模块对应的文件路径名
模块的__name__属性 用来记录模块自身名字 print(__name__) #'__main__'
模块的__all__列表:用来存放可导出属性的字符串列表
模块的私有属性 _object,当下划线开头的属性,在模块或类外不可以使用,不能用'from moduleimport *'导入。这是作者的想法,但是想调用还是有方法的。不建议调用
类的私有属性 __object,私有属性在类的外部无法直接进行访问。
高阶函数
什么是高阶函数,接受一个或者多个参数传入并且返回函数的函数,哈哈,是不是很绕,我们直接吃栗子吧
这里介绍几个高阶函数map、filter
递归和闭包还有装饰器这些大家感兴趣的话,大家了解一下,这里就不详细介绍了。
文件操作
打开文件
f = open("file",mode = 'rt',encoding = 'utf-8')
读文件,"r"
写文件,"w",写一个文件的时候,如果文件存在,会清空内容;如果文件不存在,会创建文件
以二进制形式,"b"
以文本形式,"t"
f.readline() 返回一行内容 返回是字符串格式
f.readlines() 以列表形式返回所有行内容,换行符也会读到
f.write("hello") # 如果写入的文件有内容,会清空内容再写入,如果没有.txt文件,会先创建再写入
默认文件中存储的是以字节为单位,二进制文件操作需要用字节串进行读写,f.read()返回的是字节串
f = open("abc.txt","rb")
关闭文件
f.close()
错误与异常
语法:
try:
语句
except 异常名:
语句
- 先执行try语句里面的语句,如果没有异常发生,忽略except语句,try子句执行后结束。
- 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。
- 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。(try可以嵌套try)
try: x = int(input("请输入一个错误:")) break except ValueError: print("不是有效数字,再试一遍")
try-except 用来捕捉异常
try-finally 用来做一定要做的事情
reise 用来发生异常通知
assert 用来根据天硬件发出AssertionError类型的异常通知
高级异常
但是呢?我们用的更多的是高级异常,with语句,我们来看看他的语法
with 表达式 as 变量1:
语句块
作用:使用与对资源访问的场合,确保使用过程中不管发不发生异常,都会执行“清理”操作,并且释放资源。
比如:文件打开使用后会自动帮我们关闭
面向对象
哈哈哈,终于讲了这么久终于讲到正题了,python语言的精髓——面向对象实现。
那么何为对象?何为类?大家知道吗?OKOKOKKOKOKO...我们先给大家普及一下概念吧?
对象:此对象非彼对象?python中的对象,是指现实中的物体实体化,对象有很过属性(名字、年龄..),也有很多行为(学习、吃饭..)实例即对象
实例化:类的具体对象化,实例就是类的实例化,d = got(),d即为实例
类:拥有相同属性和方法的对象集合称为类
方法:类中定义的函数
好了好了,讲这么概念,大家也是迷迷糊糊,我们直接吃个栗子,来进一步的了解一下吧!
class Myclass: #定义一个自己的类 """一个简单的类实例""" i = 12345 #类变量 def f(self,name): #定义类的方法 return("你好呀!%s"%name) # 实例化类 用x来绑定以便后面使用,不然用完之后就释放了 x = Myclass() # 把一个类变成具体对象的过程叫做实例化(初始化) # 访问类的属性和方法 print("Myclass类的属性i为:",x.i) print("Myclass类的方法f为:",x.f('名字'))
初始化方法
1、初始化方法会在构造函数创建实例后自动调用,且将实例自身通过第一参数self传入__init__方法
2、实例方法至少有一个形参,第一个形参代表调用这个方法的实例,一般命名为'self',因此类可能会定义一个名为__init__()的特殊方法
3、类定义了__init__()方法的话,类的实例化对象会自动调用__init__()方法,__init__()有形参时,参数会通过__init__()传递到实例化对象上
4、类的方法与普通的函数只有一个特殊的区别————他们必须有一个额外的第一参数名称self,按照惯例它的名称是self,谁调用这个类的方法,self就指向谁。
类的方法
前面说过,类的方法也就是类中定义的函数,类的方法与外面定义的函数不同之处就是....类的方法第一个形参必须是self。
class people: #定义一个类 # 定义类的属性 name = '' age = 0 # 定义私有属性,私有属性在类外部无法直接进行访问 _weight = 0 # 定义构造的方法 def __init__(self,n,a,w): # 定义类的初始化属性 self.name = n self.age = a self._weight = w # 定义类的方法 def speak(self): print("%s说:我%d岁"%(self.name,self.age)) # 实例化类 把一个类变成具体对象叫做类的实例化 p = people("作者",18,30) p.speak()
面向对象思想中还会有继承问题、多继承问题、以及方法重写等等。
python中的下划线
这一节内容实在不知道放哪里才合适,但是不讲有不好,毕竟我们以后会经常遇到、用到。
_object
“单下划线”开始的成员变量叫做保护变量,变量名_object被看见作是“私有”的,意思是只有类对象和子类对象自己能访问到这些变量,在模块和类外不能使用,不能用from module import * 导入,懂得用_xxx来保护变量是一种很好的习惯。PS:虽说不能访问,但是你非要访问还是有办法的,不过我觉得,我不说你也不会知道,那么我不说了。
__object
表示类的私有变量名,只有类对象自己能访问,连子类对象也不能访问到这个数据
__object__
特殊方法识别标志,系统定义的名字,那么是谁私有呢?官方私有!如:__init__()代表类的构造函数。
我们在是使用的过程中,尽量避免使用下划线作为变量,一来怕和系统变量名从掉,二来除非你不希望别人访问。还有一种下划线是在中间的,这种下划线非常支持使用,因为这能使你命名的变量名让人看得懂myname-->my_name,还有一种驼峰命名方法MyName,变量名只能由数字、字母和下划线组成,但是只能以单词下划线开头,这些你们都知道。
好的!初级python基础我暂时就讲到这里了,希望我的这次分享能给大家带来帮助,也感谢大家给我这次锻炼自我,表现的机会。
如果大家觉得这篇博客对大家有帮助,那不妨我们加个支付宝好友吧。我就是想给你们的小树苗浇浇水。[滑稽表情](放心,不是收款码,真心加好友。)