学习一门新的语言,应当抓住语言的共有特性,这样容易触类旁通,学习起来也十分的快捷愉悦
而语言的特性大约有以下元素
- 变量定义与类型
- 算术符号与逻辑符号
- for 循环与 while 循环
- 数组,线性表等一些常用的数据结构
- 函数的定义与调用
- 递归
- 静态类型系统
- 类型的推导
- lambda 函数
- 面向对象
- 垃圾回收
- 异常检测
如果你对一个语言以上的元素都有了大致了解(事实上其实并不需要花太多时间),那么你就可以愉快的开始使用啦~
1.变量的定义与类型
变量的定义
-
python里变量的定义十分简单 不需要像java里需要进行声明
例如i = 0
变量的类型
Pyhton里的变量类型分为整数型(int)
浮点型(float)
字符型(str)
布尔值类型(bool)
其中bool类型的对错是首字母大写的True
与False
,非0的字符(包括int,float,str)如果转义会被转成True
而0则是False
这点有点类似于Javascript
字符串的格式化
- python中的字符串支持参数的方式 如
"{a} love {b}".format(a="i", b="u")
结果为i love u
可以看作是使用了变量进行了代替 - 同样可以使用数字位置的参数进行替换如
'{0} love {1}.format('i', 'u')'
结果为i love u
- 如果限制格式那么使用 : 例如
'{0:.2f}'.format(45.5688)
结果为45.57
- 要进行格式化操作的话 这样使用
'%c' % 97
结果为a
,因为%c 是进行ASCII码的转化 ,多个参数使用元组或者字典'%d + %d = %d' % (4,5,9.1)
结果为4 + 5 = 9
, 这里用一个列表介绍各种格式符号的意思
符号 | 含义 |
---|---|
%c | 格式化ASCII码 |
%d | 格式化整数 |
- 当然还有一些是用来辅助操作的
符号 | 说明 |
---|---|
m.n | m是显式的最小总宽度,n是小数点后的位数 |
- | 用于左对齐 |
+ | 在正数前面显式加号 |
# | 在8进制前面显示0,在16进制数前面显式0x或者0X |
0 | 显式的数字前面填充0取代空格 |
2.逻辑符号与运算符符号
逻辑符号
- and or not 对应java的 && || !
运算符
- 基本运算符包括
+ - * / ** //
- ** 的意思是阶乘 例如 3 ** 2 = \(3^2\) = 9
- python里/ 除号默认是float,若要变成类似java的两个取整的,就使用//符号 例如
3/2=1.5
,3//2=1
3.For循环与While循环
for循环
for i in range(0,10):
print (i, end='')
输出结果0 1 2 3 4 5 6 7 8 9
pyhton里的for循环类似于java5中的foreach循环,对循环体里的每个对象进行操作
while循环
i = 0
while i < 10:
print(i, end=' ')
i += 1
输出结果0 1 2 3 4 5 6 7 8 9
需要注意的是python里的循环体语法后面要加上一个冒号哦 :)
4.数组,元组与线性表
数组中常用的api
可以通过dir(list)
来查看相关api
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
- 构建一个数组
array = [1,2,3,'hello']
- 要添加元素使用append,
array.append(x)
- extend类似于java里的addAll
array.extend(list2())
- remove
array.remove('hello')
- 按照下标删除数组里的东西
del array[1]
,如果是del array
,那会直接把这个那个数组删除掉 - 也可以使用pop()函数
array.pop()
,不写参数时是默认删除最后一个元素,可以通过填写下标来删除指定的元素 数组的分片
array[a:b]
,a代表可以的索引值,b代表结束的索引值(但是不包括这个元素),例如array[0:2]
就等于[1,2]
,也可以不指定a或者b,这样是默认从头开始,一直到结尾,例如array[:]
获得了原数组的拷贝[1,2,3,'hello']
- reverse,
array.reverse()
数组列表反转 - count,
array.count(1)
,统计数组里1出现的次数 - index,
array.index(1)
返回指定元素的下标 -
其他方法自己看api啦
数组中的操作符
- 使用操作符 + 对数组进行拼接,例如
list1 = [1, 2] list2 = [3, 4] list3 = list1 + list2
,那么list3里面内容就是[1,2,3,4]
但是需要注意的是 + 操作符两边的对象类型要保持一致list3 = list1 + 3
显然就是错误的 - 使用操作符 * 可以达到数组的拷贝与拼接例如进行
array *= 2
的操作过后array =[1,2,3,'hello',1,2,3,'hello']
- 使用操作符 = 可以达到数组地址的引用
in
与not in
返回一个bool类型的结果,例如'hello' in array
返回True'hello' not in array
返回False
元组(tuple)
- 元组的操作和数组十分类似,不同的是元组是不可变的,可以理解为java里的final类型的数组
- 元组的构建的核心是 , 逗号
tuple01 = (1)
,这样的构建方式type(tuple01)的结果就是int, 正确的构建方式是类似于这种tuple01 = (1,)
tuple01 = (1, 2, )
,如果要构建一个空的元祖使用tuple01 = ()
-
如果要对元组进行更新,删除,添加等改变状态的操作,一般是使用: 重新构建出一个新的元组,例子如下
tuple01 = (1, 2, 3) #下面我想要在该元组后面加入一个新的元素 tuple02 = tuple01[:] + (4,) print (tuple02) #那么tuple02 = [1,2,3,4] , 那么更新与删除的操作与上面就同样类似了
线性表
集合的本质是由数组构成的有序线性表,因此大部分语法与数组相同
-
集合的构建
list()
空列表list(iterable)
参数为可迭代的对象>>> b= 'I LOVE YOU' >>> b = list(b) >>> b ['I', ' ', 'L', 'O', 'V', 'E', ' ', 'Y', 'O', 'U']
- 集合的正常操作api与数组和元组十分类似,可以使用help(list)进行查看
- 一些集合中常用的辅助函数 假设有这么一个集合
list1 = list([1,2])
-
sum()
求和sum(list)
结果为3
-
max(),min()
最大值与最小值 -
enumerate()
将索引与值拼接成一个元组返回list(enumerate(list1))
结果为[(0, 1), (1, 2)]
zip
打包list2 = list([3,4,5])
根据索引值将2个集合的数据拼成一个元组返回 例list(zip(list1,list2))
结果为[(1, 3), (2, 4)]
,对应不上的就舍去了,所以5没有在结果中
5.函数的定义与调用
函数的定义
def helloWorld():
print ('i love programe!')
python中的函数参数形式
-
指定参数传递
输出结果为def say(name, word): print (name, 'say', word) say(word = 'hello!', name = 'I')
I say hello!
-
默认参数
def say(name = 'i' , word = 'helloWorld!'): print(name + '\r say \r ' + word say() say('you','good')
输出结果为
>>> say() i say helloWorld! >>> say('you', 'good') you say good
-
参数列表
def say(*name): for x in name print (x) say(1,2,3)
输出结果为
1,2,3
一般使用参数列表建议后面的参数使用默认参数例如def say(*name, word='say hello!'): for x in name: print (x, word)
函数(function )与过程(produce )
在python里没有过程,只有函数,即使是没有return的函数依旧有一个返回值,这点与java
不同
测试
def voidType():
print ("Hello World!")
#打印出该函数的返回值
print (voidType())
#使用type函数来获得该函数的返回值
type(voidType())
结果如下
>>> print (voidType())
HelloWorld!
None
>>> type(voidType())
HelloWorld!
<class 'NoneType'>
可以看到打印的是None
,而使用type函数得到的结果是NoneType
,说明了在python中没有produce只有function
函数关键字global
在python中的函数不能对外部变量进行修改,可以访问,这点与java8的函数类似,也保持了函数无状态的性质。
-
关键字global的使用,看下面这个例子
count = 5; def myFun(): count = 10 print(count) myFun() print(count)
运行结果是
10 5
在python里如果在函数里定义了局部变量,变量名与全局变量相同(在上面的例子是count变量分别在外部和函数里被定义了一次),那么函数体内使用的就是局部变量(采取了就近原则)
如果要定义全局变量,使用global关键字count = 5; def myFun(): global count #这里的定义是不能直接赋值的,比如global count = 10 这种写法 count = 10 print(count) myFun() print(count)
运行结果是
10 10
注意,这里看起来是对全局变量进行了修改,但我的理解是这里并不是进行修改,是内部重新定义了一个全局变量count,然后进行了赋值,自然就覆盖掉了全局的变量,依旧没有打破无状态的原则。
与其他语言的对比
与java的对比
- 访问与修改
在java中,在方法中可以访问和修改全局变量 - 局部变量的定义
局部变量不能和全局变量同名,否则编译不通过
-
与javaScriptd对比
1.访问与修改
在javaScript中,与python一样,函数中可以对全局变量进行访问,但是不能修改
2.局部变量的定义
与pyhton相反,如果不加上关键字var
,则默认是全局变量,如果同名就直接顶替,必须加上关键字var
才声明为局部变量
(在pyhton中是,不加关键字默认为局部变量,只有加上关键字global
才是全局变量)
内嵌函数
python中支持在函数体内定义函数,作用范围限于函数体内
def fun1():
print ('fun1() is running!')
def fun2():
print('fun2() is running!')
fun1()
运行结果为
fun1() is running!
fun2() is running!
闭包
在上面已经提到,函数体内部可以访问全局变量,但是在外部却无法访问局部变量,而闭包
就是提供了外部能够访问内部函数的变量和函数的一个入口,这点与javaScript
中的闭包概念一样,有点类似于java类中提供的getset方法,而提供这个这么一个访问入口的函数,就称之为闭包
简单的说,闭包可以理解为"定义在一个函数内部的函数,提供了外部访问的入口"
或者是"一个能够读取函数内局部变量的函数"
闭包的用途
1.上面提到的可以使得外部可以进行访问
2.既然可以供外部访问或是引用,那么这些局部变量就可以被保存到内存中,并且这些局部变量所依赖的函数,也同样的被保存了,不会被gc给回收掉。
下面是一个闭包的例子
def fun1(x):
def fun2(y)
return x * y
return fun2
fun3 = fun1(2) # 这里fun3获得了fun2的引用,成功的访问到了局部函数,所以fun2函数就是一个闭包
fun3(3) # 这里结果是 2 * 3 = 6
再一个例子
def fun1():
x = 5
def fun2():
nonlocal x # 在python2.x中,无法对外部变量进行修改,但在3.x中,引入nonlocal关键字,则可以进行修改,debug查看之后发现,外部变量确确实实的被改变了,不过我觉得这打破了函数体内不能拥有状态的这条性质....
x *= 5
return fun2()
fun2()# 运行结果为25
当然了这里的fun2()同样是一个闭包