Python基本语法
Python是一种简而美的语言,现在学习它的人也越来越多,为了节省大家的时间,也为了自己以后的复习和使用,遂在这里整理了Python的基本语法知识点以供大家能方便的来进行快速的学习和查阅。
格式
在学习Python的基本语法之前,我们先要对它的文法格式有一定了解。
print "Hello, World!"
#这是一段Python代码
Hello, World!
如果您急于了解Python的语法特征并尽快投入使用,请略过这一部分。
注:这一部分的很多规则都是十分个人化的使用习惯,请谨以之作为参考。
代码布局
缩进
Python使用缩进分隔代码块。
一个代码块起始于一行以冒号结尾的代码,下面所有缩进相同或更多的行都被视为同一个代码块,例如:
i = 0
while i < 3:
print i
i = i + 1
0
1
2
需要注意的是,虽然Python允许使用任意数量的空格或者Tab制表符进行缩进。
但是我们平时最好养成利用4个空格进行缩进的好习惯。
另外,除非是坐标,否则最好在逗号后面加上一个空格。
注释
井号(#)常被用作单行注释符号,在代码中使用#时,它右边的任何数据都会被忽略,当做是注释,例如:
#这是一个单行注释
多行注释是用三引号包含的,例如:
'''
这是三对单引号包括的Python多行注释
和多行Str字符串的表示相同
'''
"""
这是三对双引号包括的Python多行注释
在使用的时候要注意和多行Str字符串进行区分
"""
每行最大长度
每行最好控制在79个字符内,如果必要可以接受最多84个字符。
尽量避免代码嵌套层级过多,可以通过巧妙地使用break、continue和return语句实现。
长语句换行
编写长语句时,可以使用换行符(\)换行。
在这种情况下,下一行应该与上一行的最后一个“.”句点或“=”对齐,或者是缩进4个空格符:
thisIsAVeryLong(functionCall, 'with many parameters') \
.thatReturnsAnObjectWithAnAttribute
MyModel.query.filter(MyModel.scalar > 120) \
.orderBy(MyModel.name.desc()) \
.limit(10)
如果你使用括号“()”或花括号“{}”为长语句换行,那么下一行应与括号或花括号对齐:
thisIsAVeryLong(functionCall, 'with many parameters',
23, 42, 'and even more')
对于元素众多的列表或元组,在第一个“[”或“(”之后马上换行:
items = [
'this is the first', 'set of items', 'with more items',
'to come in this line', 'like this'
]
空行
顶层函数与类之间空两行,此外都只空一行。
不要在代码中使用太多的空行来区分不同的逻辑模块,如:
def hello(name):
print 'Hello %s!' % name
def goodbye(name):
print 'See you %s.' % name
class MyClass(object):
"""This is a simple docstring."""
def __init__(self, name):
self.name = name
def getAnnoyingName(self):
return self.name.upper() + '!!!!111'
表达式和语句
一般空格规则
- 单目运算符与运算对象之间不空格(例如,-,~等),即使单目运算符位于括号内部也一样。
- 双目运算符与运算对象之间要空格。
好的:
exp = -1.05
value = (itemValue / itemCount) * offset / exp
value = myList[index]
value = myDict['key']
差的:
exp = - 1.05
value = ( itemValue / itemCount ) * offset / exp
value = (itemValue/itemCount)*offset/exp
value=( itemValue/itemCount ) * offset/exp
value = myList[ index ]
value = myDict ['key']
不能编写尤达语句(Yoda Statements,指的是类似星战中尤达大师那样颠倒句子的正常顺序):
不要拿常量与变量进行对比,应该拿变量与常量进行对比。
好的:
if method == 'md5':
pass
坏的:
if 'md5' == method:
pass
比较
- 任意类型之间的比较,使用“==”和“!=”。
- 与单例(singletons)进行比较时,使用is和is not。
- 永远不要与True或False进行比较(例如,不要这样写:foo == False,而应该这样写:not foo)。
否定成员关系检查
使用foo not in bar,而不是not foo in bar。
实例检查
使用isinstance(a, C),而不是type(a) is C`。
但是一般要避免做实例检查,建议检查实例的特性。
命名规范
- 类名称:大驼峰拼写法(CamelCase),首字母缩略词保持大写不变(HTTPWriter,而不是HttpWriter)。
- 变量名:小写加下划线(lowercase_with_underscores), 对于一些显而易见的单词可以进行缩写。
- 方法与函数名:小驼峰拼写法(lowercaseWithUnderscores)。
- 常量:大写加下划线(UPPERCASE_WITH_UNDERSCORES)。
- 预编译的正则表达式:首字母大写加下划线(Name_re)。
注:变量名我本来采取小驼峰的拼写法,后来认为或许小写加下划线的拼写方法更舒服,而已有的示例代码则不再对其做出更改,依然对变量名采用小驼峰的拼写法。预编译的正则表达式也由小写加下划线变换为首字母大写加下划线,亦同上例对已有的示例代码不做更改。
受保护的元素以一个下划线为前缀。双下划线前缀只有定义混入类(mixin classes)时才使用。
如果使用关键词(keywords)作为类名称,应在名称后添加后置下划线(trailing underscore)。
允许与内建变量重名,不要在变量名后添加下划线进行区分。
如果函数需要访问重名的内建变量,请将内建变量重新绑定为其他名称。
函数和方法的参数:
- 类方法:cls为第一个参数。
- 实例方法:self为第一个参数。
- property函数中使用匿名函数(lambdas)时,匿名函数的第一个参数可以用x替代,例如:
display_name = property(lambda x: x.real_name or x.username)
文档字符串
文档字符串规范
文档字符串的行数不同,布局也不一样。
如果只有一行,代表字符串结束的三个引号与代表字符串开始的三个引号在同一行。
如果为多行,文档字符串中的文本紧接着代表字符串开始的三个引号编写,代表字符串结束的三个引号则自己独立成一行。
def foo():
"""This is a simple docstring."""
def bar():
"""This is a longer docstring with so much information in there
that it spans three lines. In this case, the closing triple quote
is on its own line.
"""
一般来说,文档字符串应分成简短摘要(尽量一行)和详细介绍。
如果必要的话,摘要与详细介绍之间空一行。
模块头部
模块文件的头部包含有utf-8编码声明(如果模块中使用了非ASCII编码的字符,建议进行声明)。
# -*- coding: utf-8 -*-
类型
Python是一种动态类型语言,这意味着变量没有类型,因此也不需要被声明。
另一方面,值是有类型的。我们可以查询变量包含的值的类型:
a = 3
print type(a)
<type 'int'>
a = 3.14
print type(a)
<type 'float'>
a = 'hello python'
print type(a)
<type 'str'>
Python也包括了原生的数据结构,如列表和字典。
字符串 (str)
Python支持两种不同类型字符串的引用ASCII字符串和Unicode字符串。
ASCII字符串使用'...'、"..."、'''...'''或者"""..."""来分隔,其中的三重引号用来分隔多行字符串。
Unicode字符串则以一个u起始,包含Unicode字符串的字符串(使用单重或者三重的单引号或者双引号分隔的)跟在后面。
通过选择编码,可以将Unicode字符串转换成ASCII字符串,例如:
a = 'this is an ASCII string'
b = u'This is a Unicode string'
a = b.encode('utf8')
执行完这三条命令之后,得到的结果a是一个存储UTF8编码字符的ASCII字符串。
通过使用str或repr命令,许多Python对象可以被序列化成字符串,例如数字。
这两条命令非常相似,但是会产生略有不同的输出,如:
for i in [3, 'hello']:
print str(i), repr(i)
3 3
hello 'hello'
对于用户定义的类,使用特殊操作符_str_和_repr_, str和repr可以被定义/重定义,其中repr总有一个默认值。
Python字符串的另一重要特征是,像列表一样,它是一个遍历对象。
for i in 'hello':
print i
h
e
l
l
o
列表 (list)
Python列表的主要方法包括添加(append)、插入(insert)、删除(del),利用len则可以获得列表的长度:
a = [1, 2, 3]
print type(a)
<type 'list'>
a.append(8)
a.insert(2, 7)
#把数字“7”插入到列表“a”的第“2”个序列上
#原本序列为“2”及这之后的元素自动被往后移动一位
del a[0]
#把序列为“0”的元素删除掉
a[3] = 5
#为序列“3”赋值为数字“5”
print a
#Python中的序列号是从“0”开始排的
[2, 7, 3, 5]
print len(a)
4
列表可以通过诸如a[b:c]的方式被切分为一个切片,其中列表a被切分为了一个长度为(c-b)的切片,由序列b开始并包括序列b,到序列c结束但不包括序列c,b或者c可以为空值,若b为空值则代表从列表的第0个序列开始,若c为空值则代表到列表的最后一个序列结束并包括列表的最后一个序列,b和c可以同时为空值,此时切片与列表的长度相等:
print a[:3]
[2, 7, 3]
print a[1:]
[7, 3, 8]
print a[:]
[2, 7, 3, 8]
b和a的值还可以为负,此时列表的序列号从右往左依次由-1开始递减:
print a[-2:]
[3, 8]
列表还可以被连接:
a = [2, 3]
b = [5, 6]
print a + b
[2, 3, 5, 6]
通过循环语句,列表可以被遍历:
a = [1, 2, 3]
for i in a:
print i
1
2
3
列表中的元素不必是相同的类型,它们可以是Python对象的任意类型。
有一种很常见的情况,可以使用列表解析(list comprehension),请看如下代码:
a = [1,2,3,4,5]
b = []
for x in a:
if x % 2 == 0:
b.append(x * 3)
b
[6, 12]
这段代码清楚地处理了一个项目列表,选择和修改了输入列表的一个子表,并创建了一个新的结果列表。
但是用下列列表解析,可以完全代替上述代码:
a = [1,2,3,4,5]
b = [x * 3 for x in a if x % 2 == 0]
b
#在2.7.X版本下似乎对于这种写法并不支持
[6, 12]
元组(tuple)
元组由圆括号分隔,类似于列表,但是它的大小和元素是不可变的,而列表的大小和元素是可变的。
如果元组元素是一个对象,则对象的属性是可变的。
类似于列表,元组是一个遍历对象。
请注意,一个元素构成的元组必须包含一个结尾逗号,如下所示:
a = (1)
print type(a)
<type 'int'>
a = (1,)
print type(a)
<type 'tuple'>
字典(dict)
Python字典是一个哈希表,将键对象映射成值对象。例如:
a = {'k':'v', 'k2':3}
a['k']
v
a['k2']
3
a.has_key('k')
True
a.has_key('v')
False
键可以是任何哈希类型(整型、字符串,或类能实现_hash_方法的任何对象),值可以是任何类型。
在同一字典中,不同键和值不一定是相同的类型,如果键是字母数字字符,也能用替代句法声明字典:
a = dict(k='v', h2=3)
a['k']
v
print a
{'k':'v', 'h2':3}
实用的方法是has_key、 keys、values和items:
a = dict(k='v', k2=3)
print a.keys()
['k', 'k2']
print a.values()
['v', 3]
print a.items()
[('k', 'v'), ('k2', 3)]
items方法产生一元组列表,每个元组包含一个键和它的对应值。
字典元素和列表元素可以用del命令删除。
a = [1, 2, 3]
del a[1]
print a
[1, 3]
a = dict(k='v', h2=3)
del a['h2']
print a
{'k':'v'}
在内部,Python用hash运算符将对象转换成整数,并用得到的整数确定值存储在哪里。
hash("hello world")
-1500746465
流程控制
while循环与for循环
while循环在执行循环体前先判断循环次数和测试条件,如果条件为假,循环就终止。
i = 0
while i < 3:
i = i + 1
print i
1
2
3
Python中的for语句依据任意序列(列表或字符串)中的子项,按它们在序列中的顺序来进行迭代,如下:
words = ['cat', 'window', 'defenestrate']
for w in words:
print w, len(w)
cat 3
window 6
defenestrate 12
在迭代过程中修改迭代序列不安全(只有在使用列表这样的可变序列时才会有这样的情况)。
如果你想要修改你迭代的序列(例如:复制选择项),你可以迭代它的复本。
使用切割标识(切片)就可以很方便地做到这一点:
for w in words[:]:
if len(w) > 6:
words.insert(0, w)
words
['defenestrate', 'cat', 'window', 'defenestrate']
range(a,b,c)函数可以返回一个整数列表,从值a开始,递增c,结束值小于b。
range()函数的参数是可选的,而其中a的默认值是0,c的默认值是1,只有b是必须要被声明的,如下:
range(10)
#生成一个包含10个值的列表
#它用列表的索引值填充了这个长度为10的列表
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
xrange()与此类似,但不会真正生成列表,只生成一个列表的遍历,因此对于循环来说它更好。
xrange()可以产生一个遍历范围而无需存储整个列表元素:
for i in xrange(0, 4):
print i
0
1
2
3
另一种实用的函数是enumerate(),在循环的同时能计数:
a = [0, 1, 'hello', 'python']
for i, j in enumerate(a):
print i, j
0 0
1 1
2 hello
3 python
break、continue与循环中的else子句
你可以使用break跳出循环,如下:
for i in [1, 2, 3]:
print i
break
1
使用continue,你可以不执行完整个代码块就跳转到下一个循环迭代。
for i in [1, 2, 3]:
print i
continue
print 'No!'
1
2
3
循环可以有一个else子句,它在循环迭代完整个列表(对于for)后或执行条件为false(对于while)时执行。
但是else子句在循环被break中止的时候不会被执行。
以下搜索素数的示例程序演示了这个子句:
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
print n, 'equals', x, '*', n/x
break
#else语句是属于for循环之中,而不是if语句
else:
print n, 'is a prime number'
2 is a prime number
3 is a prime number
4 equals 2 * 2
5 is a prime number
6 equals 2 * 3
7 is a prime number
8 equals 2 * 4
9 equals 3 * 3
if...elif...else
在Python中使用条件语句是直观的:
for i in range(4):
if i == 0:
print 'zero'
elif i == 1:
print 'one'
elif i == 2:
print 'two'
else:
print 'other'
zero
one
two
other
"elif"代表着"else if"。
elif和else从句都是可选的,可以有多个elif从句,但只能有一个else从句。
使用not、and和or运算符可以构造复杂条件,如下:
for i in range(3):
if i == 0 or (i == 1 and i + 1 == 2):
print '0 or 1'
0 or 1