学习一门新的语言,应当抓住语言的共有特性,这样容易触类旁通,学习起来也十分的快捷愉悦而语言的特性大约有以下元素
变量定义与类型算术符号与逻辑符号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
, 这里用一个列表介绍各种格式符号的意思
当然还有一些是用来辅助操作的
2.逻辑符号与运算符符号逻辑符号and or not 对应java的 && || !运算符基本运算符包括 + - * / ** //
** 的意思是阶乘 例如 3 ** 2 = \(3^2\) = 9python里/ 除号默认是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 = 0while 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里的addAllarray.extend(list2())
removearray.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 ' + wordsay()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 = 10print(count)myFun()print(count)
运行结果是
105
在python里如果在函数里定义了局部变量,变量名与全局变量相同(在上面的例子是count变量分别在外部和函数里被定义了一次),那么函数体内使用的就是局部变量(采取了就近原则)如果要定义全局变量,使用global关键字
count = 5;def myFun():global count #这里的定义是不能直接赋值的,比如global count = 10 这种写法count = 10print(count)myFun()print(count)
运行结果是
1010
注意,这里看起来是对全局变量进行了修改,但我的理解是这里并不是进行修改,是内部重新定义了一个全局变量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 fun2fun3 = 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()同样是一个闭包
『 不可能 』只存在於蠢人的字典里