我说几句
原书地址:http://www.ituring.com.cn/book/1863(图灵社区)
有关 Python:
“人生苦短,我用Python”
Python的设计哲学是“优雅”、“明确”、“简单”。
一、基础(变量和字符串)
首先:Python 每个语句结束可以不写分号 ;
, 如 print('hello')
打印 hello
1、变量:
有过编程基础的话,变量就不多说了。
变量的命名法:
- 驼峰式命名法
- 帕斯卡命名法
2、字符串:
2.1 基本介绍
单引号 ' '
或者双引号 " "
都可以,再或者 ''' '''
三个引号,其中三个引号被用于过于长段的文字或者是说明,只要是三引号不完你就可以随意换行写下文字。
① 字符串直接能相加,如:
str1 = 'hi'
str2 = 'hello'
print(str1 + str2)
结果:hi jaybo
② 字符串相乘,如:
string = 'bang!'
total = string * 3
结果:bang!bang!bang!
2.2 字符串的分片与索引
字符串可以通过 string[x] 的方式进行索引、分片。
字符串的分片实际可以看作是从字符串中找出来你要截取的东西,复制出来一小段你要的长度,存储在另一个地方,而不会对字符串这个源文件改动。分片获得的每个字符串可以看作是原字符串的一个副本。
2.3 字符串的方法:
replace 方法:
第一个参数表示被替代部分,第二个参数表示替代成怎样的字符串。字符串填空,如:
city = input("write the name of city:"") url = "http://apistore.baidu.com/mri.../weather?citypiny={}.format(city)
2.4 问题:
问题1:
num = 1
string = '1'
print(num + string)
上面代码将出错?
解释:整数型不能和字符串直接相加。可以先把该字符串转为整数型,再相加,即 int(string)
num = 1
string = '1'
print(num + int(string))
二、函数
举些例子:
判断数据类型:type(str)
字符串类型数据转为整数型:int(str)
...
可以看到 Python 中所谓的函数就是要把你处理的对象放在一个名字后面的括号里就可以了。
以 Python3.5 版本为例,一个有68个这样的函数,它们被称为内建函数。这里內建的是指这些函数为安装好了python就可以使用,是“自带”的而已这么个意思。
定义函数的格式:
其中,def
和 return
为关键字。
注意: 函数缩进后面的语句被称为是语句块,缩进是为了表名语句的逻辑与从属关系。缩进这个问题不能忽视,否则会导致代码无法成功运行,这里需要特别注意。
① 位置参数
② 关键词参数:在函数调用的时候,将每个参数名称后面赋予一个我们想要传入的值,如调用 fun1 函数时候:fun1(a=1, b=2, c=3)
—————以下为别处补充过来的资料:—————–
③ 不定长参数
有时我们在设计函数接口的时候,可会需要可变长的参数。也就是说,我们事先无法确定传入的参数个数。Python 提供了一种元组的方式来接受没有直接定义的参数。这种方式在参数前边加星号 *
。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。例如:
def print_user_info( name , age , sex = '男' , * hobby):
# 打印用户信息
print('昵称:{}'.format(name) , end = ' ')
print('年龄:{}'.format(age) , end = ' ')
print('性别:{}'.format(sex) ,end = ' ' )
print('爱好:{}'.format(hobby))
return;
# 调用 print_user_info 函数
print_user_info( '两点水' ,18 , '女', '打篮球','打羽毛球','跑步')
输出的结果:
昵称:两点水 年龄:18 性别:女 爱好:('打篮球', '打羽毛球', '跑步')
通过输出的结果可以知道,*hobby是可变参数,且 hobby其实就是一个 tuple (元祖)
可变长参数也支持关键参数,没有被定义的关键参数会被放到一个字典里。这种方式即是在参数前边加 **,更改上面的示例如下:
def print_user_info( name , age , sex = '男' , ** hobby ):
# 打印用户信息
print('昵称:{}'.format(name) , end = ' ')
print('年龄:{}'.format(age) , end = ' ')
print('性别:{}'.format(sex) ,end = ' ' )
print('爱好:{}'.format(hobby))
return;
# 调用 print_user_info 函数
print_user_info( name = '两点水' , age = 18 , sex = '女', hobby = ('打篮球','打羽毛球','跑步'))
输出的结果:
昵称:两点水 年龄:18 性别:女 爱好:{'hobby': ('打篮球', '打羽毛球', '跑步')}
通过对比上面的例子和这个例子,可以知道,*hobby
是可变参数,且 hobby 其实就是一个 tuple (元祖),**hobby
是关键字参数,且 hobby 就是一个 dict (字典)
④ 只接受关键字参数
关键字参数使用起来简单,不容易参数出错,那么有些时候,我们定义的函数希望某些参数强制使用关键字参数传递,这时候该怎么办呢?将强制关键字参数放到某个*
参数或者单个*
后面就能达到这种效果,比如:
def print_user_info( name , *, age , sex = '男' ):
# 打印用户信息
print('昵称:{}'.format(name) , end = ' ')
print('年龄:{}'.format(age) , end = ' ')
print('性别:{}'.format(sex))
return;
# 调用 print_user_info 函数
print_user_info( name = '两点水' ,age = 18 , sex = '女' )
# 这种写法会报错,因为 age ,sex 这两个参数强制使用关键字参数
#print_user_info( '两点水' , 18 , '女' )
print_user_info('两点水',age='22',sex='男')
通过例子可以看,如果 age
, sex
不适用关键字参数是会报错的。
匿名函数
有没有想过定义一个很短的回调函数,但又不想用 def 的形式去写一个那么长的函数,那么有没有快捷方式呢?答案是有的。
python 使用 lambda 来创建匿名函数,也就是不再使用 def 语句这样标准的形式定义一个函数。
匿名函数主要有以下特点:
- lambda 只是一个表达式,函数体比 def 简单很多。
- lambda 的主体是一个表达式,而不是一个代码块。仅仅能在 lambda 表达式中封装有限的逻辑进去。
- lambda 函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
基本语法:lambda [arg1 [,arg2,.....argn]]:expression
示例:
sum = lambda num1 , num2 : num1 + num2;
print( sum( 1 , 2 ) )
输出的结果: 3
PS:尽管 lambda 表达式允许你定义简单函数,但是它的使用是有限制的。 你只能指定单个表达式,它的值就是最后的返回值。也就是说不能包含其他的语言特性了, 包括多个语句、条件表达式、迭代以及异常处理等等。
匿名函数中,有一个特别需要注意的问题,比如,把上面的例子改一下:
num2 = 100
sum1 = lambda num1 : num1 + num2 ;
num2 = 10000
sum2 = lambda num1 : num1 + num2 ;
print( sum1( 1 ) )
print( sum2( 1 ) )
你会认为输出什么呢?第一个输出是 101,第二个是 10001,结果不是的,输出的结果是这样:
10001
10001
这主要在于 lambda 表达式中的 num2 是一个自由变量,在运行时绑定值,而不是定义时就绑定,这跟函数的默认值参数定义是不同的。所以建议还是遇到这种情况还是使用第一种解法。
三、循环与判断
3.1 逻辑控制与循环:
Python 中的布尔类型值:True 和 Flase 其中,注意这两个都是首字母大写。
但凡能够产生一个布尔值的表达式为布尔表达式。
1 > 2 # False
1 < 2 <3 # True
42 != '42' # True
'Name' == 'name' # False
'M' in 'Magic' # True
number = 12
number is 12 # True
PS: 不同类型的对象不能使用”<,>,<=,=>”进行比较,却可以使用”==”和”!=”
注意:浮点类型和整数类型虽然是不同类型,但不影响比较运算。还有,不等于“!=” 可以写作“<>” 。
话说,布尔类型可以比较吗?如:True > Flase
,回答是可以的,Ture 和 Flase 对于计算机就像是1和0一样,所以结果是真,即True
。
3.2 条件控制:
定义格式:
用一句话该结构作用:如果…条件是成立的,就做…;反之,就做…
所谓条件成立,指的是返回值为True
的布尔表达式。
3.3 循环:
① for 循环:
把 for 循环所的事情概括成一句话就是:于…其中的每一个元素,做…事情。
九九乘法表的打印:
for i in range(1, 10):
for j in range(1, 10):
print('{}*{}={}'.format(i, j , i*j), end=' ')
print('\n')
结果:
1*1=1 1*2=2 1*3=3 1*4=4 1*5=5 1*6=6 1*7=7 1*8=8 1*9=9
2*1=2 2*2=4 2*3=6 2*4=8 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1=3 3*2=6 3*3=9 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1=4 4*2=8 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1=5 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1=6 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1=7 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1=8 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1=9 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
② while 循环:
总结:只要…条件一成立,就一直做…
在循环过程中,可以使用 break
跳过循环,使用 continue
跳过该次循环。
在 Python 的 while 循环中,可以使用 else 语句,while … else 在循环条件为 false 时执行 else 语句块。如:
count = 0
while count < 3:
print (count)
count = count + 1
else:
print (count)
结果:
0
1
2
3
有 while … else 语句,当然也有 for … else 语句,for 中的语句和普通的没有区别,else 中的语句会在循环正常执行完(即 for 不是通过 break 跳出而中断的)的情况下执行,while … else 也是一样。如:
for num in range(10,20): # 迭代 10 到 20 之间的数字
for i in range(2,num): # 根据因子迭代
if num%i == 0: # 确定第一个因子
j=num/i # 计算第二个因子
print ('%d 是一个合数' % num)
break # 跳出当前循环
else: # 循环的 else 部分
print ('%d 是一个质数' % num)
结果:
10 是一个合数
11 是一个质数
12 是一个合数
13 是一个质数
14 是一个合数
15 是一个合数
16 是一个合数
17 是一个质数
18 是一个合数
19 是一个质数
四、数据结构
python 有四种数据结构,分别是:列表、字典、元组、集合。我们先从整体上认识一下这四种数据结构:
list = [val1,val2,val3,val4] #列表
dict = {key1:val1,key2:val2} #字典
tuple = (val1,val2,val3,val4) #元组
set = {val1,val2,val3,val4} #集合
① 列表(List)
1.列表中的每个元素都是可变的;
2.列表中的元素是有序的,也就是说每个元素都有一个位置;
3.列表中可以容纳 Python 中的任何对象。如下:
all_in_list = [
1, #整数
1.0, #浮点数
'a word', #字符串
print(1), #函数
True, #布尔值
[1,2], #列表中套列表
(1,2), #元祖
{'key':'value'} #字典
]
对于数据的操作,最常见的为增删改查。
……
② 字典(Dict)
1. 字典中数据必须是以键值对的形式出现的;
2. 逻辑上讲,键是不能重复的;
3. 字典中的键(key)是不可变的,也就是无法修改的,而值(value)是可变的,可修改的,可以是任何对象。下面是个例子:
NASDAQ_code = {
'BIDU':'Baidu',
'SINA':'Sina',
'YOKU':'Youku'
}
一个字典中键与值并不能脱离对方而存在,如果你写成了 {‘BIDU’:} 会引发一个语法错误:invalid syntax。
如果试着将一个可变(mutable)的元素作为 key 来构建字典,比如列表:key_test = {[]:'a Test'}
,则会报一个错:unhashable type:'list'
。
同时字典中的键值不会重复,即便你这么做,相同的键值也只能出现一次:a = {'key':123,'key':123}
。
增删改查操作……列表中用来添加多个元素的方法为extend
,在字典中添加多个元素的方法为update()
字典是不能切片的,即这样的写法是错误的:chart[1:4]
③ 元组(Tuple)
元组可以理解为一个稳固版的列表,因为元组是不可以修改的,因此在列表中的存在的方法均不可以使用在元组上,但是元组是可以被查看索引的,方式和列表一样。
letters = ('a, 'b', 'c', 'd')
letters[0]
④ 集合(Set)
集合则更接近数学上集合的概念。每一个集合中是的元素是无序的、不重复的任意对象,我们可以通过集合去判断数据的从属关系,有时还可以通过集合把数据结构中重复的元素减掉。
集合不能被切片也不能被索引,除了做集合运算之外,集合元素可以被添加还有删除:
a_set = {1,2,3,4}
a_set.add(5)
a_set.discard(5)
数据结构一些技巧:
1、多重循环
for a, b in zip(num, str):
print(b, 'is', a)
2、推导式
a = []
for i in range(1, 11):
a.append(i)
可以换成列表解析的方式来写:
b = [i for in i range(1, 11)]
列表解析式不仅方便,并且在执行效率上要远远胜过前者。
五、类与可口可乐
定义:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
使用 class 来定义一个类,就如同创建函数时使用的 def 定义一个函数一样简单。
类的属性:
- 类变量
- 方法
实例化:
coke_for_me = CocaCola()
coke_for_you = CocaCola()
类属性的引用:CocaCola.formula
、coke_for_me.formula
实例方法:
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def drink(self):
print('Energy!')
coke = CocaCola()
coke.drink()
self
coke = CocaCola
coke.drink() == CocaCola.drink(coke) #左右两边的写法完全一致
被实例化的对象会被编译器默默地传入后面方法的括号中,作为第一个参数。上面两个方法是一样的,但我们更多地会写成前面那种形式。其实self
这个参数名称是可以随意修改的(编译器并不会因此而报错)。
魔术方法
Python的类中存在一些方法,被称为「魔术方法」,_init_()
就是其中之一。
class CocaCola():
formula = ['caffeine','sugar','water','soda']
def __init__(self):
self.local_logo = 'ݢݗݢԔ'
def drink(self): # HEREѺ
print('Energy!')
coke = CocaCola()
printcoke.local_logo)
作用:在创建实例之前,它做了很多事情。说直白点,意味着即使你在创建实例的时候不去引用 init_() 方法,其中的语句也会先被自动的执行。这给类的使用提供了极大的灵活性。
class CocaCola:
formula = ['caffeine','sugar','water','soda']
def __init__(self,logo_name):
self.local_logo = logo_name
def drink(self):
print('Energy!')
coke = CocaCola('ݢݗݢԔ')
coke.local_logo
>>> 可口可乐
类的继承
如下:
class CaffeineFree(CocaCola):
caffeine = 0
ingredients = [
'High Fructose Corn Syrup',
'Carbonated Water',
'Phosphoric Acid',
'Natural Flavors',
'Caramel Color',
]
coke_a = CaffeineFree('Cocacola-FREE')
coke_a.drink()
表示 CaffeineFree 继承了 CocaCola 类。
类中的变量和方法可以被子类继承,但如需有特殊的改动也可以进行覆盖。
Q1:类属性如果被重新赋值,是否会影响到类属性的引用?
class TestA():
attr = 1
obj_a = TestA()
TestA.attr = 24
print(obj_a.attr)
>>> 结果:24
A1:会影响。
Q2:实例属性如果被重新赋值,是否会影响到类属性的引用?
class TestA:
attr = 1
obj_a = TestA()
obj_b = TestA()
obj_a.attr = 42
print(obj_b.attr)
>>> 结果:1
A2:不会影响。
Q3:类属性实例属性具有相同的名称,那么.
后面引用的将会是什么?
class TestA():
attr =1
def __init__(self):
self.attr = 24
obj_a = TestA()
print(obj_a.attr)
>>> 结果:24
A3:类属性赋值后的值。
总结:如图所示,Python 中属性的引用机制是自外而内的,当你创建了一个实例之后,准备开始引用属性,这时候编译器会先搜索该实例是否拥有该属性,如果有,则引用;如果没有,将搜索这个实例所属的类是否有这个属性,如果有,则引用,没有那就只能报错了。
六、使用第三方库
安装自己的库
我们一般使用 pip 来进行第三方库的安装,那么自己的库要怎么安装呢?当然可以把自己的库提交到 pip 上,但是还要添加一定量的代码和必要的文件才行,在这里我们使用一个更简单的方法:
1. 找到你的 Python 安装目录,找到下面的 site-packages 文件夹;
2. 记住你的文件名,因为它将作为引用时的名称,然后将你写的 py 文件放进去。
这个文件夹应该有你所安装的所有第三方库。如果你并不清楚你的安装路径,可以尝试使用如下方式搞清楚它究竟在哪里:
import sys
print(sys.path)
打印出来的会是一个列表,列表中的第四个将是你的库安装路径所在,因此你也可以直接这么做:
import sys
print(sys.path[3])
令人惊叹的第三方库
如果用手机来比喻编程语言,那么 Python 是一款智能机。正如含量的手机应用出现在 iOS、Android 平台上,同样有各种各样的第三方库为 Python 开发者提供了极大的便利。
当你想要搭建网站时,可以选择功能全面的 Django、轻量的 Flask 等 web 框架;当你想写一个小游戏的时候,可以使用 PyGame 框架;当你想做一个 爬虫时,可以使用 Scrapy 框架;当你想做数据统计分析时,可以使用 Pandas 数据框架……这么多丰富的资源可以帮助我们高效快捷地做到想做的事,就不需要再重复造轮子了。
那么如何根据自己的需求找到相应的库呢?可以到 awesome-python.com 这个网站上按照分类去寻找,上面收录了比较全的第三方库。比如想要找爬出方面的库时,查看 Web Crawling 这个分类,就能看到相应的第三方库的网站与简介,可以进入库的网站查看更详细的介绍,并确认这个库支持的是 python 2 还是 python 3,不过绝大多数常用库已经都支持了这两者。另外,你也可以直接通过搜索引擎寻找。
安装第三方库方式:
① 最简单的方式:在 PyCharm 中安装
- 在 pycharm 的菜单中选择:File -> Default Setting
- 搜索 project interpreter,选择当前python版本,点击“+”添加库
- 输入库的名称,勾选,并点击 Install Package
在安装成功后, pycharm 会有成功提示。也可以在 project interpreter 这个界面中查看安装了哪些库,点“-”号就可以卸载不再需要的库。
② 最直接的方式:在终端/命令行中安装
1、安装 pip
在 python 3.4 之后,安装好 python 环境就可以直接支持 pip,你可以在终端/命令行里输入这句检查一下:pip --version
(前提电脑path路径已经配置好了)如果显示 pip 版本,就说明 pip 已经成功安装了;如果发现没有安装,则根据不同系统如下方式安装:
2、使用 pip 安装库
在安装好了pip之后,以后安装库,支需要在命令行里面输入:pip3 install PackageName
(注:如果你想要安装到 python 2 中,需要把 pip3 换成 pip)
如果你安装了 python 2和3 两种版本,可能会遇到安装目录的问题,可以换成:python3 -m pip install PackageName
(注:如果你想安装到 python2 中,需要把 python3 换成 python)
如果遇到权限问题,可以输入:sudo pip install PackageName
安装成功之后会提示:Successfully insyalled PackageName
介绍几个 pip 的常用指令:
pip install --upgrade pip #升级pip
pip uninstall flask #卸载库
pip list #查看已安装库
3、最原始的方式:手动安装
进入pypi.python.org,搜索你要安装的库的名字,这时候有3种可能:
- 第一种是 exe 文件,这种最方便,下载满足你的电脑系统和 python 环境的对应的 exe,再一路点击 next 就可以安装。
第二种是 .whl 类文件,好处在于可以自动安装依赖的包。
1)到命令行输入
pip3 install whell
等待执行完成,不能报错(python 2中要换成 pip)
2)从资源管理器中确认你下载的 .whl 类文件的路径,然后在命令行继续输入:cd C:\download
,此处需要改为你的路径,路径的含义是文件所在的文件夹,不包含这个文件名字本身,然后再命令行继续输入:pip3 install xxx.whl
xxx.whl 是你下载的文件的完整文件名。第三种是源码,大概都是 zip、tar.zip、tar.bz2 格式的压缩包,这个方法要求用户已经安装了这个包所依赖的其他包。例如 pandas 依赖于numpy,你如果不安装 numpy,这个方法是无法成功安装 pandas 的。
1)解压包,进入解压好的文件夹,通常会看见一个 setup.py 的文件,从资源管理器中确认你下载的文件的路径,打开命令行(cmd),输入:
cd C:\download
此处需要改为你的路径,路径的含义是文件所在的文件夹,不包含这个文件名字本身
2)然后在命令行中继续输入:python3 setup.py install
这个命令,就能把这个第三方库安装到系统里,也就是你的 Python路径,windows 大概是在C:\Python3.5\Lib\site-packages
。
想要卸库的时候,找到 python 路径,进入 site-packages 文件夹,在里面删掉库文件就可以了。