TOP


目录

语法基础

... 注释

... 输入输出

... 变量

... 缩进

数据类型

... 布尔型

... 数字

... 字符串

... List,Tuple

... Set

... Dictionary

流程控制

... 判断

... 循环

... Pass

函数、模块

... 函数

... 模块

语法基础

注释

后面的代码示例中会出现文字说明注释代码含义,所以在最前面讲一下注释:
单行注释:以 # 开始,到行尾,但如果在单引号或双引号之间就是字符串了

>>> #这是一条注释
>>> str = '#This is not a comment'
'#This is not a comment'

多行注释:文件中,可以用'''...''' 或者 """..."""表示注释,即:三个双引号/单引号开始,到三个双引号/单引号结束,之间的都是注释语句:

实际上,在标准的Python中这其实是一个多行字符串:

这在后面的多行字符串中再讲吧。

输入输出

学习一门语言只用眼睛看是不行的,有些内容以为自己看明白了,合上书一写就漏洞百出,所以必须得动手练习。我们先简单介绍标准输入输出以辅助后面的练习。

输出:print

>>> print('Hello')
Hello
>>> #可以不加括号:
>>> print 'Hello'
Hello
>>> #多个字符串用逗号分隔跟在print后面,会连成一个空格分隔的大串:
>>> print 'Hello', 'World'
Hello World
>>> #可直接打印计算结果:
>>> print 1 + 2
3
>>> #输入变量名直接打印变量值:
>>> i = 3
>>> i
3
>>> s = 'hello'
>>> s
'hello'

输入:raw_input

>>> name = raw_input()
linhl
>>> print name
linhl
>>> #可增加输入提示的参数:
>>> name = raw_input('请输入姓名: ')
请输入姓名: linhl
>>> print name
linhl

变量

Python是一个动态语言,从前面的代码示例可以看出,我们使用变量的时候都没有指定变量类型,直接写 变量名 = ... 。

变量名只能包含字母、数字和下划线,且不能以数字开头。

定义的变量即要为其赋值,使用未赋值的便利会得到错误:

>>> q

Traceback (most recent call last):
  File "<pyshell#119>", line 1, in <module>
    q
NameError: name 'q' is not defined

在Python Shell中,最后一次打印的表达式会赋给变量 _ :

In interactive mode, the last printed expression is assigned to the variable _. This means that when you are using Python as a desk calculator, it is somewhat easier to continue calculations, for example:

tax = 12.5 / 100
price = 100.50
price * tax
12.5625
price + _
113.0625
round(_, 2)
113.06

可以进行多变量一次赋值:

>>> x,y,z = 1,2,3
>>> x
1

缩进

Python的代码块是通过冒号和缩进定义的,像是函数,if,for,while等等,都是在冒号分隔后,相同缩进的是其代码体。缩进一般是四格,但也不是硬性规定,一致就行,最好不要用Tab

def add(x,y):
    return x + y

if __name__ == "__main__":
    print add("abcd","hijk")
    print add(1,10)

每行语句用回车分隔,不需要封号。

数据类型

关于内置类型的详细说明请见Python标准库的官方文档,下面只做一些基础及常用的介绍:

布尔型

True,False

真值校验

所有对象都可以做真值校验。以下值会被解释器认为是False:

  • None
  • False
  • 数字类型的0:0,0L,0.0,0j
  • 空序列:'',(),[]
  • 空字典:{}
  • 定义了__nonzero__() 或 len() 方法的类的实例,并且方法的返回值是 0 或 False

其它对象都会被认为是True。

布尔操作符

x or y if x is false, then y, else x 只有x为False时才会判断y
x and y if x is false, then x, else y True时才会判断y
not x if x is false, then True, else False

注意 or和and返回的不是True或False,而是x或y本身

数字

整数:int, long(L 后缀)

小数:float

复数:complex

对数字进行加减乘除操作时,结果是int还是float,取决于操作数本身的类型,如果两个操作数都是int则结果也是int(向下取整),只要有一个操作数是float结果就是float:

>>> a = 6
>>> b = 2
>>> a/b
3
>>> a = 6.0
>>> a/b
3.0

常用操作符

>>> 17/3.2        # int / float -> float
5.3125
>>> 17//3.2       # // 表示向下取整
5.0
>>> 17%3          # % 取余
2
>>> 8 ** 3        # ** m**n: m的n次方,等价于:pow(m,n)
512
>>> abs(-10)      # 绝对值
10
>>> int(1.7)      # 转为整形
1
>>> long(1.7)     # 转为长整形
1L
>>> float(1)      # 转为浮点型
1.0
>>> divmod(11,2)  # (x // y, x % y)
(5,1)
>>> max(1,2,3)    # 最大值
3
>>> min(1,2,3)    # 最小值
1

字符串

定义

字符串用单引号或双引号包括,两者都行,用单/双引号包括时,字符串中出现的单/双引号需要加 \ 转义:

>>> print '"What\'s your name?",he asked.'
"What's your name?",he asked.
>>> print "\"What's your name?\",he asked."
"What's your name?",he asked.

\表示转义,如要输出\本身而不需要转义,可用\\,也可在字符串前加 r 表示原样输出。请自行实验:print 'a\b' print 'a\\b' print r'a\b'

多行字符串

讲注释的时候有提到多行字符串,多行字符串用 '''...'''"""...""" 表示:

>>> str = '''
a
b
c
'''
>>> print str

a
b
c

>>> # 相当于自动加了 \n :
>>> str
'\na\nb\nc\n'

如果打印时不想换行,就加一个\

>>> str = '''a
b\
c
'''
>>> print str
a
bc

>>> str
'a\nbc\n'

\ 是续行符,一条命令也可以用它来分成多行:

>>> if a == b \
	   and a > 0 :
		print a
	else:
		print b

连接

可以通过将多个字符串并排进行连接显示,也可以用 + 连接,但是变量和表达式只能用 + 连接:

>>> 'Hello ' 'World'      # 等价于 'Hello ' + 'World'
'Hello World'
>>> a = 'Hello '
>>> a + 'World'           # 不能写成 a 'World',变量必须用 + 连接
'Hello World'
>>> 'ab' * 3 + 'cd'       # * 表示重复,表达式必须用 + 连接
'abababcd'
>>> # 演示一个使用场景:
>>> text = ('Put several strings within parentheses '
    'to have them joined together.')
>>> text
'Put several strings within parentheses to have them joined together.'

格式化

格式化的字符串包括被替换的字段,有以下几种方式:

通过位置替换

>>> '{0},{1}'.format('Hello','World')
'Hello,World'
>>> '{0},{1}  {0},{1}'.format('Hello','World')  # 参数可多次使用
'Hello,World  Hello,World'

通过参数名替换

>>> '{name},{age}'.format(name='linhl',age=34)
'linhl,34'

通过参数的属性替换

>>> class Point(object):
		def __init__(self, x, y):
			self.x, self.y = x, y
		def __str__(self):
			return 'Point({self.x}, {self.y})'.format(self=self)
>>> str(Point(4,2))
'Point(4, 2)'

通过参数的元素替换

>>> coord = (3, 5)
>>> 'X: {0[0]};  Y: {0[1]}'.format(coord)
'X: 3;  Y: 5'

可以在字段后面加 ":" 和格式指令,对值的格式化加以更多控制:

>>> # 设置字段的最小宽度
>>> for x in range(1,5):
		print '{0:d} {1:2d} {2:2d}'.format(x, x**2, x**3)

1  1  1
2  4  8
3  9 27
4 16 64

>>> # 设置精度
>>> import math
>>> print 'The value of PI is approximately {0:.3f}.'.format(math.pi)
The value of PI is approximately 3.142.

zfill() 可以向数值字符串左侧添加0:

>>> '123'.zfill(5)
'00123'
>>> '-123'.zfill(5)
'-0123'
>>> '12345'.zfill(5)
'12345'

索引, 分片

>>> word = 'Python'
>>> word[0]  # 第一个字母
'P'
>>> word[-1]  # 最后一个字母
'n'
>>> word[2:5]  # 第三个字母开始到第五个字母,左闭右开,包括2不包括5
'tho'
>>> word[:2] + ',' + word[4:]
'Py,on'

关于字符串更多的内容参见官方文档

List,Tuple

list(列表)和tuple(元组)都是sequence(序列)。

list :

>>> list = [1,2,3,4]
>>> list[0] = 5              # 可修改
>>> list
[5, 2, 3, 4]
>>> list.append(6)           # 向末尾添加一个元素
>>> list
[5, 2, 3, 4, 6]
>>> list.insert(1,0)         # 向指定的索引位置添加
>>> list
[5, 0, 2, 3, 4, 6]
>>> list.extend([7, 8, 9])   # 将另外一个list添加到本list的末尾
>>> list
[5, 0, 2, 3, 4, 6, 7, 8, 9]
>>> list + [10,11,12]        # 两个list连接
[5, 0, 2, 3, 4, 6, 7, 8, 9, 10, 11 ,12]
>>> 5 in list                # 检测某个元素是否在list中
True
>>> 1 in list
False
>>> list.remove(5)           # 移除指定元素
>>> list.pop()               # 移除最后一个元素,并返回
9
>>> list.pop(1)              # 移除指定索引的元素,并返回
2
>>> list
[0, 3, 4, 6, 7, 8]

tuple :

>>> tuple = (1,)          #只有一个元素时需要加一个逗号
>>> tuple = (1,2,3,4)
>>> tuple[0] = 5          # 不可修改

Traceback (most recent call last):
  File "<pyshell#249>", line 1, in <module>
    tuple[0]=5
TypeError: 'tuple' object does not support item assignment

>>> tuple.append(5)       # 不可修改

Traceback (most recent call last):
  File "<pyshell#252>", line 1, in <module>
    tuple.append(5)
AttributeError: 'tuple' object has no attribute 'append'

>>> tuple + (1,2,3)
(1, 2, 3, 4, 1, 2, 3)

tuple没有方法,不能做增删改查。它的速度比list快,当你需要一个常量集(其中的数据不可修改),或者需要频繁遍历一个常量集的时候,请使用tuple。

list和tuple都可以索引和分片,与上面字符串的一致,分片后会得到新的list/tuple。

把列表当堆栈使用

堆栈的特点是“后进先出”,列表所具有的方法可以很容易实现:使用append() 向列表末尾增加元素(向栈顶添加元素),使用pop() 移除列表最后一个元素(释放栈顶的元素)。

>>> stack = [1,2,3]
>>> stack.append(4)
>>> stack.append(5)
>>> stack
[1,2,3,4,5]
>>> stack.pop()
5
>>> stack.pop()
4
>>> stack
[1,2,3]

把列表当队列使用

队列的特点是“先进先出”,用列表实现效率会比较低,因为每次在头部插入或弹出元素时,需要移动列表中的全部元素。这时我们可以使用 collections.deque

>>> from collections import deque
>>> queue = deque([1,2,3])
>>> queue.append(4)
>>> queue.append(5)
>>> queue
deque([1,2,3,4,5])
>>> queue.popleft()
1
>>> queue.popleft()
2
>>> queue
deque([3,4,5])

Set

set 是一个无序的、无重复元素的集合,一般用于成员检测及剔除重复的条目。

>>> # 可以使用大括号或set()定义set
>>> a = {1,1,2,2,3}
>>> a
set([1, 2, 3])
>>> a = set([1,1,2,2,3])
>>> a
set([1, 2, 3])
>>> # 只能使用 set() 定义空set,而不能使用 {} , {}定义的是空字典
>>> a = set()
>>> type(a)
<type 'set'>
>>> a = {}
>>> type(a)
<type 'dict'>

Dictionary

dictionary(字典)定义了 key-value 键值对,是无序的。

>>> d = {"name":"linhl","age":34}
>>> d["name"]                  # 通过key获取value
'linhl'
>>> d["name"] = "LinHaiLu"     # 修改key对应的value
>>> d["name"]
'LinHaiLu'
>>> d["gender"] = "female"     # 增加key-value
>>> d["gender"]
'female'
>>> d
{'gender': 'female', 'age': 34, 'name': 'LinHaiLu'}
>>> d.keys()                   # 获取所有键
['gender', 'age', 'name']
>>> "gender" in d              # 判断键是否存在
True
>>> del d["gender"]            # 删除key-value
>>> d
{'age': 34, 'name': 'LinHaiLu'}
>>> d.clear()                  # 清空
>>> d
{}

如果一个列表的元素是键值对元组,可以用dict直接构造成dictionary:

>>> list = [('a',1),('b',2),('c',3)]
>>> dict(list)
{'a': 1, 'c': 3, 'b': 2}

如果使用字符串做key,使用关键字参数更简单:

>>> dict(a=1,b=2,c=3)
{'a': 1, 'c': 3, 'b': 2}

流程控制

判断

>>> x = int(raw_input("Please enter an integer: "))
Please enter an integer: 10
>>> if x > 10 :
		print 'large'
elif x < 10:
		print 'small'
else:
		print 'equal'

equal

这是一个完整的判断语句,如果熟悉C,或者java,或者javascript,是不是有点不适应?条件没有用小括号括起来,只在最后加了冒号;开始结束也没有花括号,难道靠缩进呀?没错,Python为了给大家养成良好的编码习惯,提高代码的可读性,就是用缩进代表块的。大家可以自己试试看,不写缩进或者乱写缩进会出现什么情况。

循环

for

>>> words = ['a','ab','abc','abcd']
>>> for w in words:
		print w

a
ab
abc
abcd

不能在循环中修改当前list,如有需要则要对这个list的拷贝进行循环:

>>> words = ['cat', 'window', 'defenestrate']
>>> for w in words[:]:  # 借用分片得到一个新的list
		if len(w) > 6:
			words.insert(0, w)

>>> words
['defenestrate', 'cat', 'window', 'defenestrate']

如需遍历数字序列,可以使用range()

>>> # range() 自身的用法:
>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(2,8)
[2, 3, 4, 5, 6, 7]
>>> range(2,10,3)     # 设置步长
[2, 5, 8]
>>> # range()配合for循环:
>>> days = ['Mon.','Tues.','Wed.','Thurs.','Fri.','Sat.','Sun.']
>>> for i in range(len(days)):
		print i+1,days[i]
1 Mon.
2 Tues.
3 Wed.
4 Thurs.
5 Fri.
6 Sat.
7 Sun.

使用 break 跳出循环,continue 跳过后续步骤进入下一个循环:

>>> for i in range(10):
		if i%2 == 0 :
			continue
		print i
		if i > 5:
			break


1
3
5
7

对列表循环,索引和对应的值可以使用 enumerate() 得到:

>>> for i,v in enumerate(['a','b','c']):
		print '{0} : {1}'.format(i,v)

0 : a
1 : b
2 : c

对字典循环,关键字和对应的值可以使用 iteritems() 得到:

>>> d = dict(a=1,b=2,c=3)
>>> for k,v in d.iteritems():
		print '{0} : {1}'.format(k,v)

a : 1
c : 3
b : 2

while

满足条件时不断循环,直到不满足为止:

>>> i = 0
>>> while i < 10:
		i = i + 2

>>> print i
10

Pass

pass 代表一个空块,相当于占位,不做任何处理:

>>> for i in range(6):
	if i%2 == 0:
		pass
	else:
		print i
	
1
3
5

还可以用来定义空类:

class MyEmptyClass:
	pass

空函数:

def initlog(*args):
	pass

函数、模块

函数

函数申明以 def 开始,然后是函数名,参数。参数在小括号中,多个参数用逗号分隔。不需要指定返回值类型,也不需要指定是否有返回值,实际上,每个Python函数都有返回值,如果执行了return语句就返回指定的值,否则返回None

函数申明后的第一个内容,我们一般写一个多行字符串,作为函数的doc string。这块内容从解释器的角度来说不是必须的,但对于好的编码习惯来说是必须的。doc string在运行时可以作为函数的属性(__doc__);有些IDE把doc string作为上下文文档信息,在输入函数名时显示为工具信息。

以下是一个简单的函数定义以及调用的示例:

# MyFirst.py
def add(x,y):
    """计算x+y
    x和y的类型必须一致
    """
    return x + y

if __name__ == "__main__":
    print add.__doc__
    print add("abcd","hijk")
    print add(1,10)

这里的if __name__ == "__main__" 语句我们在下面的模块中介绍。

重命名:

>>> a = add
>>> print a(10,20)
30

参数

Python函数的参数使用非常灵活,们通过示例来看:

缺省参数

# 设置参数的缺省值,有缺省值的参数必须跟在无缺省值参数的后面
>>> def showInfo(str1,str2,times1=1,times2=2):
	    print str1*times1,str2*times2

# 普通调用
>>> showInfo("a","b",2,4)
aa bbbb
# 使用缺省值
>>> showInfo("a","b")
a bb
# 使用一个缺省值
>>> showInfo("a","b",2)         # times2取缺省值
aa bb
# 通过关键字参数指定值
>>> showInfo("a","b",times2=4)  # times1取缺省值
a bbbb
# 通过关键字参数打乱传参顺序
>>> showInfo(str2="b",str1="a")
a bb

需要注意,缺省值在方法被定义的时候赋值,并且只赋值一次。在使用list、dictionary、类实例作为缺省值时要特别注意:

>>> i = 1
>>> # 定义函数的时候缺省值是1
>>> def f(arg=i):
		print arg

>>> i = 2
>>> 虽然变量变了,但是函数的缺省值还是1
>>> f()
1

看看用list做缺省值:

>>> def f(a,L=[]):
		L.append(a)
		return L
>>> print f(1)
[1]
>>> print f(2)
[1,2]

原理其实就是这样的:

>>> list = []
>>> def f(a,L=list):
		L.append(a)
		return L

可以这样改进:

>>> def f(a, L=None):
		if L is None:
		    L = []
		L.append(a)
		return L
>>> f(1)
[1]
>>> f(2)
[2]

可变参数

如果在定义函数时,不知道参数的个数,那么可以用一个以*为前缀的参数来接收可变数量的参数:

>>> def f(a,b,*c):          # c是一个tuple,接收a和b后面所有的值
		print a,b,c

>>> f(1,2,3,4,5)
1 2 (3, 4, 5)               # 3,4,5作为一个tuple被c接收
>>> f(1,2)
1 2 ()

传递已有的list或tuple可以这样:

>>> list = [6,7,8]
>>> f(1,2,*list)            # 在list前面加一个 *
1 2 (6, 7, 8)
>>> f(1,2,list)             # 注意区别
1 2 ([6, 7, 8],)

关键字参数

前面有提到关键字参数,也就是可以显式指定参数值赋给哪个形参。我们还可以使用一个以**为前缀的参数来接收关键字参数:

>>> def f(a,b,**c):         # c是一个dictionary,接收a和b后面的关键字参数
		print a,b,c

>>> f(1,2)
1 2 {}
>>> f(1,2,x=3,y=4)
1 2 {'y': 4, 'x': 3}

传递已有的dictionary可以这样:

>>> d = {'x':3,'y':4}
>>> f(1,2,**d)             # 在d前面加 **
1 2 {'y': 4, 'x': 3}

内置函数

Python有一些常用的内置函数,都在__builtin__模块下,可以直接使用:

type 返回任意对象的数据类型

>>> type(1)
<type 'int'>
>>> type("a")
<type 'str'>
>>> import MyFirst
>>> type(MyFirst)
<type 'module'>
>>> type(add)
<type 'function'>

str 将数据强制转换为字符串

>>> str(1)
'1'
>>> d = {'a':1,'b':2}
>>> str(d)
"{'a': 1, 'b': 2}"
>>> str(MyFirst)
"<module 'MyFirst' from 'C:\\Users\\hailu\\Desktop\\MyFirst.py'>"
>>> str(add)
'<function add at 0x00000000028A0828>'
>>> str(None)
'None'

dir 返回任意对象的属性和方法列表

>>> dir(1)        # int
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> dir("")       # 字符串
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>> dir({})       # dictionary
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']
>>> dir([])       # list
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> dir(())       # tuple
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index']
>>> dir(MyFirst)  # MyFirst 模块
['__builtins__', '__doc__', '__file__', '__name__', '__package__', 'a', 'add', 'buildConnStr', 'showInfo']
>>> dir(add)      # add 函数
['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']

变量作用域

需要注意一个变量作用域的问题,比如下面的例子,大家认为运行结果会怎样:

# 全局变量
name = 'a'

# 函数
def do_something():
	print name
	name = 'b'
	print name

do_something()
print name

试验一下看结果与自己想的是否一致?

为什么会出现这种情况(UnboundLocalError: local variable 'name' referenced before assignment)?因为在函数中可以访问全局变量,但是不能修改,一旦出现赋值语句,Python会找同名的局部变量,但是找不到,所以抛出了异常。如果一定要在函数中修改全局变量,可以在修改前加一句申明:

...
def do_something():
	...
	global name      # 表明现在访问全局变量
	name = 'b'
	...

模块

可以把一个Python文件看作一个模块,其中可以定义变量、函数、类,也可以直接写可执行代码语句。但并不是所有的模块都必须是.py文件,像内置模块,它们是用其它语言写的。

使用import 来引用一个模块,这样我们才能使用这个模块中的函数。例如上面讲函数时在MyFirst.py中定义了一个add函数,现在要在另一个模块中使用,需要这样写:

# 将add从MyFirst模块导入到局部命名空间
from MyFirst import add
print add(1,2)

或者:

# 调用方法时必须加上模块名进行限定
# 此种方式可以避免命名冲突
import MyFirst
print MyFirst.add(1,2)

那么Python是怎么找到MyFirst这个模块的呢?原来Python是对sys.path中定义的目录进行搜索的。sys.path是一个list,我们可以查看并修改它:

>>> import sys
>>> sys.path
['C:\\Users\\hailu\\Desktop', 'D:\\Python27\\Lib\\idlelib', 'C:\\Windows\\SYSTEM32\\python27.zip', 'D:\\Python27\\DLLs', 'D:\\Python27\\lib', 'D:\\Python27\\lib\\plat-win', 'D:\\Python27\\lib\\lib-tk', 'D:\\Python27', 'D:\\Python27\\lib\\site-packages']

如果你需要的模块不在sys.path的目录中,可以使用 sys.path.append() 追加目录。

所有模块都有一个内置属性:__name__ 。当本模块直接运行时,它是一个缺省值 __main__ ,当在其它模块中被import 时,它的值是模块的文件名,不带文件路径和文件扩展名。利用这一特性,我们可以为模块添加测试组件,例如函数一节的示例中,if __name__ == "__main__" 语句,它的作用有点类似于java在每个类中写的Main函数,当本模块独立运行的时候执行,当被其它模块调用时不会执行。这样我们很方便地在编写模块时进行测试。

Package

使用package可以避免命名空间冲突的问题。package就是含有__init__.py文件(可以是空文件)的目录。例如:

E:\MyPython\
			test1\
				  __init__.py
				  MyFirst.py
			test2\
				  __init__.py
				  MyFirst.py

test1和test2是两个package,其下有相同名称的module。

>>> import sys
>>> sys.path.append("E:\\MyPython")
>>> import test1.MyFirst
>>> import test2.MyFirst
>>> test1.MyFirst.add(1,2)
__name__ is test1.MyFirst
3
>>> test2.MyFirst.add(1,2)
__name__ is test2.MyFirst
3
posted on 2015-06-02 18:05  爱雪的木木  阅读(354)  评论(0编辑  收藏  举报