最近学习使用了一下python,觉得跟C或Java相比里面有不少比较奇特的
地方
。下面列一些Python语言在基本概念和用法上的的特殊之处。
每个
对象都有type。 对象一旦创建,type就不再改变
if
logging
对象
每个
对象都有id,或者可以认为是对象的地址。对象一旦创建,id就不再改变
id(obj):返回对象idis(obj1, obj2):比较两个对象的id是否相同对象的id和对象的值不是一回事
type(obj):返回对象类型
某些类型的 对象的值可以改变:
list, dictionary, ...
某些类型的
对象的值不可以改变:
number, string, tuple, ...
对象的创建
除了显式创建对象, 对象创建也会发生在赋值操作时
对象的销毁
不显式销毁对象。由垃圾搜集器销毁那些已经无法被程序引用的对象
变量
每个
变量,可以认为它的值是
对象的id,即对象的地址(或者引用)
变量其实不是一个Python对象,所以没有id。但形式上,谈到变量id的时候,就是指它的值,也即它所指对象的id
赋值语句
如果左侧仅仅是变量名自身,赋值语句会改变该变量所指的对象(此时
创建新对象,将新对象的id作为值赋予该变量)
如果左侧是一个值可变的复杂对象的子对象(如list中的一个元素),赋值语句相当于为该子对象赋值,但变量的值没有变,仍然指向
原先的对象
简单但不严格地说(写得拗口,比较难理解):
如果变量原先所指对象的值是可变的,则对象的id不变,只改变值如果变量原先所指对象的值是不可变的,则将新对象的id赋予该变量
还是结合实例来说明会比较清楚:
# 例:赋值后,变量所指向的对象发生了变化
>>> c=5 # 5是一个值不可变的对象。应该说,c记录了5这个对象的地址,而不是c的值是5
>>> id(c)
22587160
>>> c=10 # 10是另一个值不可变的对象。现在c记录了这个新对象的地址,
这是和C/Java的明显区别
>>> id(c)
22587100
>>> c='abc' # 'abc'是另一个值不可变的对象。现在c记录了这个新对象的地址
>>> id(c)
22731448
#
例:
对对象进行一些操作,不影响变量所指向的对象id
>>> a=[1,2] # [1,2]是一个值可变的对象。现在a记录了这个新对象的地址
>>> id(a)
27617680
>>> a.append(3)
>>> id(a)
27617680
>>> a[1]=5 # 5是一个值不可变的对象。现在a[1]记录了这个新对象的地址
>>> id(a)
27617680
# 例:a=a+b 与 a+=b 的效果不同
>>> a=[1]
>>> b=[2]
>>> id(a),id(b)
(27643256, 27643336)
>>> a=a+b
>>> id(a)
27642056
>>> a=[1]
>>> b=[2]
>>> id(a),id(b)
(27643256, 27642056)
>>> a+=b
>>> id(a)
27643256
函数参数传递
简单但不严格地说 (写得拗口,比较难理解) :形参是一个变量,它的值等于实参的值,也就是说, 指向同一个对象
若函数内改变了形参的值(对象id),则实参所指对象的值不受影响若函数内不改变形参的值,但改变了对象的值,则实参所指对象的值受影响
对值不可以改变的类型,参数看上去像是使用了传值方式对值可以改变的类型,参数看上去像是使用了传递引用的方式
变量作用域
使用global指明全局符号
模块
每个python
文件(.py)即为一个模块(module)
模块无层次结构:模块不可以包含其它模块
包(package)包含模块
具有层次结构,还可以包含其它包。对应文件系统中的目录
控制流
elif
else
while
else
for ... in ...
else
continue
break
while
else
异常处理
try
except
else
finally
raise
OO
class xxx (super-class):
def __init__()def __del__()
特殊变量
__name__
__doc__
文档
测试
module doctest
module unittest
常用标准模块
threading
zipfile
re
ConfigParser
csv
md5
sha
email
json
htmllib
xml.*
urllib
locale