第3章 Python基础
本章主题
- 语句和语法
- 变量赋值
- 基本风格指南
- 内存管理
- 第一个python程序
3.1语句和语法
python中有一些基本规则和特殊字符:
- (#)井号表示之后为字符为python的注释
- (\n)换行是标准的行分隔符
- (\)反斜线表示继续上一行
- (;)表示将两个语句连在一行中
- (:)冒号表示将代码块的头和体分开
- 语句(代码块)用于缩进的方式体现
- 不同的缩进深度分隔不同的代码块
- python文件以模块的形式组织
3.1.1注释(#)
解释器会忽略掉#之后的内容
3.2.1继续(/)
python语句,一般使用换行分隔,也就是说一行一个语句,一行过长的语句可以使用反斜杠(\)分解成几行。
在三引号时候可以跨行书写。
括号的可读性更好。
3.1.3多个语句构成代码(:)
缩进相同的一组语句构成一个代码块,我们称之为代码组。像if、while、def、class 这样的复合句。首行以关键字开始,以冒号(:)结束,改行之后的一行或多行被称之为代码组。
我们将首行及后面的代码称之为字句(clause)
3.1.4代码组不同的缩进分隔
python使用缩进来分隔代码组。代码的层次关系是通过同样深度的空格或制表符的缩进体现。同一代码组的代码必须严格左对齐。
核心风格:缩进4个空格宽度,避免使用制表符。
随着缩进深度的增加,代码块的层次也在增加,没有缩进的代码块是最高的层次的,被称之为主体(main)部分。
3.1.5同一行书写多个语句(;)
(;)分号允许你在同一行书写多个语句,之间用分号隔开。这些语句不能再这行开始的一个新的代码块。
例子:
import sys;x='foo';sys.stdout.write(x+'\n')
3.1.6模块
每个python脚本都可以被当做一个模块。模块以磁盘文件的形式存在。当一个模块。
当一个模块过大,并且驱动了很多功能的话,就应该考虑拆一些代码出来另外建一个模块。
模块里面代码可以是一段直接可执行的脚本,也可以是一堆类似库函数的代码,从而可以被别的模块导入(import)调用。
3.2 变量赋值
3.2.1赋值操作符
python语言中,等号(=)是主要的赋值操作符(其他的是增量操作符)
如:
anInt=12
在python语言中,对象是通过引用传递的。python的赋值语句不会返回值。
>>> x=1
>>> y=(x=x+1) #赋值语句不是合法表达式
SyntaxError: invalid syntax
>>> y=x=x+1
>>> x,y
(2, 2)
3.2.2增量赋值
x=x+1
等价于
x+=1
增量赋值符,其一是写法上的简化,其二是第一个对象进被处理一次。
可变对象呗修改,不可变对象则和A=A+B的结果一样。
>>> m=12
>>> m%=7
>>> m
5
>>> m**=2
>>> m
25
>>> aList=[123,'xyz']
>>> aList+=[45.6e7]
>>> aList
[123, 'xyz', 456000000.0]
3.2.3多重赋值
>>> x=y=z=1
>>> x
1
>>> y
1
>>> z
1
该对象的同一个引用被赋值给x、y、z
3.2.4 “多元”赋值
将多个变量同时赋值的方法我们称之为多元赋值(multuple)
>>> (x,y,z)=(1,2,'a string')
>>> x
1
>>> y
2
>>> z
a string
两个整型和一个字符串分别被赋值给x、y、z
python的多元赋值方法可以实现无需中间变量交换。
3.3标识符
3.3.1合法的python标识符
python的标识符规则和其他大部分用C编写的高级语言类似:
- 第一个字符必须是字母或者下划线(_)
- 剩下的字符可以是字符和数字或下划线。
- 大小写敏感
3.3.2关键字
3.3.3内建
python有任何一级代码使用的“内建”(built-in)的名字集全。把built-in当做“系统保留字”。
3.3.4专用下划线标识符
python用下划线作为变量前缀和后缀指定特殊变量。
对python下划线的特殊用法做了总结:
- _xxx 不用‘from module import *’导入
- _xxx_ 系统定义名字
- _xxx 类中的私有变量名
核心风格:避免下划线作为变量名的开始
3.4基本风格指南
注释
确保注释的准确性。注释对自己和他人都很重要。
文档
python提供了一个机制,可通过__doc__特别变量,动态获得文档字串。在模块、类声明、或函数声明第一个没有赋值的字符串可以用属性obj.__doc__来访问。
obj是一个模块、类、或函数的名字。
缩进
缩进对其十分重要,增强代码可读性。不要使用制表符。
选择标识符名称
选择短的有意义的标识符。
python风格指南
3.4.1模块的结构和布局
用模块来合理组织你的python代码是简单又自然的方法。如下面的布局:
#(1)起始行
#(2)模块文档
#(3)模块导入
#(4)变量定义
#(5)类定义
#(6)函数定义
#(7)主程序
(1)起始行
通常只在类unix环境下使用。
(2)模块文档
简要介绍模块的功能及重要全局变量的含义,模块可通过 moudle.__doc__访问这些内容
#/usr/bin/env python (1)起始行
“this is a test module” (2)模块文档
import sys
import os (3)模块导入
debug=True (4)(全局)变量
class FooClass(object):
“Foo class”
pass (5)类定义
def test():
“test function”
foo=FooClass()
if debug:
print ‘ran test()’ (6)函数定义(若有)
of __name__==’__main__’:
test() (7)主程序
(3)模块导入
导入当前模块的代码需要的所有模块,每个模块仅导入一次(当前模块加载时);函数内部的模块导入代码不会被执行,除非该函数正在执行。
(4)变量定义
这里定义的变量为全局变量,本模块中的所有函数都可以直接使用。
尽量使用局部变量代替全局变量,代码易维护,且提高性能节省内存。
(5)类定义语句
所有的类都在这里定义,当模块被导入时,class语句就会被执行。类也就会被定义。类的文档变量是class.__doc__
(6)函数定义语句
函数语句可以通过module.function()被外部访问到,当模块被导入时def语句会被执行,函数也就都会定义好。函数的文档变量是function.__doc__
(7)主程序
无论这个模块是被别的模块导入还是作为脚本直接执行,都会执行这部分代码。
核心风格:主程序调用main()函数。
绝大部分模块的创建目的是为了被别人调用而不是作为独立执行的脚本。
核心风格:__name__指示模块应如何被加载
- 如果模块是被导入,__name__的值为模块名字
- 如果模块是被直接执行,__name__的值为‘ __main__ ’
3.4.2 在程序中书写测试代码
3.5 内存管理
- 变量无须事先声明
- 变量无须指定类型
- 程序员不用关心内存管理
- 变量名会被“回收”
- del语句能够直接释放资源
3.5.1 变量定义
python中,无须此类显式声明语句,在第一次被赋值时候自动声明。
>>> a
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
a
NameError: name 'a' is not defined
变量一旦被赋值,就可以直接通过变量名来访问他们。
>>> x=4
>>> y='this is a string'
>>> x
4
>>> y
'this is a string'
3.5.2 动态类型
python无须类型声明。
3.5.3 内存分配
底层的事情交给python解释器去做就可以了。
3.5.4 引用计数
要追踪内存中的对象,python引用了计数这一简单技术。
1.增加引用计数
2.减少引用计数
3.del语句
3.5.5垃圾收集
不再使用的内存被一种称之为垃圾收集的机制释放。
3.6第一个python程序
例3-1 创建文件(makeTextFile.py)
这个脚本是在提醒用户输入一个(尚不存在)的文件名,然后由用户输入该文件的每一行。最后,将所有的文本写入文本文件。
#!usr/bin/env/python
'makeTextFile.py--create text file'
import os
ls=os.linesep
#get filename
while True:
if os.path.exists(fname):
print "ERROR: '%s' already exists" % fname
else:
break
#get file content(text) lines
all=()
print "\nEnter lines (' . ' by itself to quit).\n"
#loop until user terminates input
while True:
entry=raw_input('>')
if entry==' . ':
break
else:
all.append(entry)
#write lines to file with proper line-ending
fobj=open(fname,'w')
fobj.writelines(['%s%s' %(x,ls) for x in all])
fobj.close()
print 'DONE!'
3.7 相关模块和开发工具
《python风格指南》《python快速指南》
调试器:pdb
记录器:logging
性能测试器:profile、hotshot
第4章 python对象
本章主题:
- python对象
- 内建类型
- 标准类型操作符
- 值的比较
- 对象身份比较
- 布尔类型
- 标准类型内建函数
- 标准类型总览
- 各种类型
- 不支持的类型
4.1 python对象
python使用对象模型来存储数据。构造任何类型的值都是一个对象。
python的对象有三个特性:身份,类型,和值。
身份:每个对象都有一个唯一的身份标识自己。
类型:对象的类型决定了该对象可以保存什么类型的值。可以用type()函数查看对象的类型。
值:对象表示的数据项。
对象属性
含有数据属性的对象包括,类,类实例,模块,复数,文件。
4.2标准类型
- 数字
- Integer 整型
- Boolean 布尔型
- Long Integer 长整型
- Floating point real number 浮点型
- Complex number 复数型
- String 字符串
- List 列表
- Tuple 元组
- Dictionary 字典
4.3其他内建类型
- 类型
- Null对象(None)
- 文件
- 集合/固定集合
- 函数/方法
- 模块
- 类
4.3.1类型对象和type类型对象
内建函数type()
>>> type(32)
<type 'int'>
<type ‘int’>是一个类型对象。
>>> type(type(32))
<type 'type'>
所有类型对象的类型都是type,它是所以python类型对象的根和所有python标准类的默认元类(metaclass)。
4.3.2 None——Python的Null对象
Python有一个特殊对象,被称为Null对象或NoneType,它只有一个值,那就是None。不支持任何运算也没用任何内建方法。
None没有任何属性,布尔值为False
核心笔记:布尔值。
所有标准对象均可用于布尔测试,同类型的对象之间可以比较大小。每个对象天生具有布尔True和False
下面的对象布尔值为False:
- None
- False(布尔类型)
- 所有值为零的数
- 0(整型)
- 0.0(浮点型)
- 0L(长整型)
- 0.0+0.0j(复数)
- “”(空字符)
- [](空列表)
- ()(空元组)
- {}(空字典)
除上面以外的所有对象的布尔值都是True
4.4 内部函数
- 代码
- 帧
- 跟踪记录
- 切片
- 省略
- Xrange
4.4.1 代码对象
代码对象是一个函数的属性。
代码对象是编译过的python的源代码,是可执行对象,通过调用函数compile()可以得到代码对象。
4.4.2 帧对象
帧对象表示python的执行帧栈。帧对象包含python解释器在运行时候所需要知道的所有信息。
4.4.3 跟踪记录对象
代码出错时,python会报错。发生异常时,一个包含针对异常的栈跟踪信息的跟踪记录对象被创建。
4.4.4 切片对象
使用python扩展的切片语法时候,就会创建切片对象。
包括多维切片,步进切片,省略切片。
多维切片语法:sequence[start1:end1,start2:end2]
省略切片语法:sequence[…,start1:end1]
步进切片语法:sequence[起始索引:结束索引:步进值]
如:
>>> f='abcdef'
>>> f[::-1]
'fedcba'
>>> f[::-2]
'fdb'
>>> fr=[123,'abc',123.456,'qwe']
>>> fr[::-1]
['qwe', 123.456, 'abc', 123]
4.4.5 省略对象
省略对象用于扩展切片语法中,起记号作用。这个对象在切片语法中表示省略号。类似Null对象None
省略对象的有唯一名字Ellipsis ,布尔值为True
4.4.6 XRange对象
调用内建函数xrange()会生成一个Xrange对象。
4.5标准类型操作符
4.5.1对象值的比较
所有内建类型均支持比较运算,比较运算返回值布尔值为True或False
>>> 2==2
True
>>> 2==3
False
>>> 'abc'<'xyz'
True
>>> 'abc'>'xyz'
False
>>> [5,'abc']== [5,'abc']
True
>>> [5,'abc']== ['abc',5]
False
4.5.2 对象身份的比较
为方便理解,我们举例:
例1:f1和f2指向相同对象
f1=f2=4
例2:f1和f2指向相同对象
f1=4
f2=f1
4.5.3布尔类型
布尔逻辑操作符 and,or,not都是python的关键字
not操作符拥有最高的优先级。
>>> x,y=3.1415926,-1024
>>> x<5.0
True
>>> not (x<5.0)
False
>>> (x<5.0 )or (y>2.71828)
True
>>> (x<5.0 ) and (y>2.71828)
False
>>> not (x is y)
True
4.6标准类型内建函数
还有一些标准类型的内建函数:
cmp()、repr()、str()、type()、repr()函数的单反引号(` `)操作符
函数cmp() 比较函数,根据比较结果返回整形
函数repr() 返回一个对象的字符串表示
函数str() 返回对象社会可读性好的字符串表示
函数type() 得到一个对象的类型,并返回相应的type对象
4.6.1 type()
内建函数type(),用法如下:
type(object)
type()接受一个对象作为参数,并且返回他的类型,它的返回值是一个类型对象。
>>> type(4) #整型
<type 'int'>
>>> type('Hello World!') #字符型
<type 'str'>
>>> type(type(4)) #type类型
<type 'type'>
4.6.2 cmp()
若obj1<obj2 返回-1
若obj1>obj2 返回1
若obj1=obj2 返回0
若用户自定义对象,cpm()函数会调用该类的特殊方法__cmp__
>>> cmp(a,b)
-1
>>> cmp(b,a)
1
>>> b=-4
>>> cmp(a,b)
0
4.6.3str() 和repr()函数的单反引号(` `)操作符
str() 和repr()函数的单反引号(ˋˋ)操作符 可以方便的以字符串的方式获取对象的内容、类型、数值属性等信息。
str()函数得带的字符串可读性好;
repr()函数得带的字符串通常用来重新获取对象。
>>> str(4.53)
'4.53'
>>> str(1)
'1'
>>> str(2e10)
'20000000000.0'
>>> str([0,1,2,3])
'[0, 1, 2, 3]'
>>> repr(1)
'1'
>>> repr([0,1,2,3,4])
'[0, 1, 2, 3, 4]'
>>> `[0,1,2,3]`
'[0, 1, 2, 3]'
repr()和(` `)做的事情几乎完全一样,返回一个对象的“官方”字符串表示。可以同eval()重新得到该对象。
str()则是致力于生产一个对象的可读性好的字符串表示,适用于print()语句。
并非所有的repr()返回的字符串都可以用eval()内建函数来得到原来的对象。
>>> eval(`type(type)`)
Traceback (most recent call last):
File "<pyshell#24>", line 1, in <module>
eval(`type(type)`)
File "<string>", line 1
<type 'type'>
^
SyntaxError: invalid syntax
为什么我们有了repr()函数还需要(“)
因为某些场合函数会比操作符更适合使用。(现在不鼓励使用(“))
4.6.4 type()和isinstance()
>>> type('')
<type 'str'>
>>> s='xyz'
>>> type(s)
<type 'str'>
>>> type(0+0j)
<type 'complex'>
>>> type([])
<type 'list'>
>>> type({})
<type 'dict'>
>>> type(0.0)
<type 'float'>
>>> type(0L)
<type 'long'>
4.6.5 python类型操作符和内建函数总结
4.7 类型工厂函数
内建转换函数int()、 type() 、 list(),现在都成了工厂函数。
虽然他们看上去像函数,但是他们是类。
4.8 标准类型的分类
标准类型:python的“基本内建数据对象原始类型”
4.8.1 存储模型
4.8.2 更新模型
请看下列代码:
>>> x='python'
>>> print id(x)
23849088
>>> x='what?'
>>> print id(x)
30706720
>>> i=0
>>> print id(i)
23945996
对象实际上对替换了。
>>> List=['abd',65,34,'dad']
>>> List
['abd', 65, 34, 'dad']
>>> List[2]
34
>>> id(List)
30671536
>>> List[2]=List[2]+1
>>> List[3]='dsrge'
>>> List
['abd', 65, 35, 'dsrge']
>>> id(List)
30671536
列表的值不论如何变换,列表的ID始终不变。
4.8.3 访问模型
4.9 不支持的类型
下面给出python目前还不支持的数据类型。
1. char和byte
python没有char或byte类型来保存单一字符或8位整型
2. 指针
python替你管理内存,没必要访问指针
3. int vs short vs long
python的整型相当于C语言中的长整型
4. float vs double
python的浮点型实际上是C语言的双精度浮点型
第5章 数字
本章主题
- 数字简介
- 整型
- 布尔型
- 标准整型
- 长整型
- 浮点型实数
- 复数
- 操作符
- 内建函数
- 其他数字类型
- 相关模块
本章主要内容:
详细介绍每一种数字类型,他们使用的各种操作符,以及用于处理输的内建函数。以及简单介绍了几个标准库中用于处理数字的模块。
5.1数字简介
数字提供了标量存储和直接访问。是不可更改类型,也就是说变更数字的值会生成新的对象。
python支持多种数字类型:
整型、长整型、布尔型、双精度浮点型、十进制浮点型和复数
5.1.1 如何创建数值对象并用其赋值(数字对象)
anInt=1
aLong=-999999999L
aFloat=3.141592653
aComplex=1.23+4.56J
5.1.2 如何更新数字对象
通过对数字对象(重新)赋值,可以更新一个数值对象。
变量就像一个盒子,我们无法改变盒子的内容,但是可以将指针指向一个新盒子。
5.1.3如何删除数字对象
无法真正删除数值对象,仅仅是不再使用而已
5.2整型
5.2.1布尔型
该类型取值范围:布尔值True和布尔值False
5.2.2 标准整型
5.2.3长整型
python的长整型类型能表达的仅仅与你的机器支持的虚拟内大小有关
核心风格:大写字母L表示长整型
>>> aLong=999999991
>>> aLong=99999999L
>>> print aLong
99999999
5.2.4 整型和长整型的统一
5.3 双精度浮点型
浮点型通常是都有一个小数点和一个可选的后缀e
5.4 复数
复数由实数部分和虚数部分组成
虚数部分必须有后缀j
表示虚数的语法:real+imagj
复数的内建属性
>>> aComplex=-8.333-1.47j
>>> aComplex
(-8.333-1.47j)
>>> aComplex.real
-8.333
>>> aComplex.imag
-1.47
>>> aComplex.conjugate()
(-8.333+1.47j)
num.real 复数的实部
num.imag 复数的虚部
num.conjugate() 复数的共轭复数
5.5 操作符
5.5.1 混合模式操作符
类型转换基本原则:
整型转换为浮点型,非复数转换为复数
>>> 5+1.5
6.5
5.5.2 标准类型操作符
不同类型之间运算,在运算之前,python会将两个操作数转换为同一数据类型
>>> -719>=920
False
>>> 2<5<8
True
>>> 0.<-90.4<55.3e2!=3<181
False
>>> (-1<1) or (1<-1)
True
5.5.3 算术操作符
支持单目操作符:正号(+)和负号(-)
双目操作符:+、-、*、%、** (分别表示加法、减法、乘法、除法、取余、幂运算)
>>> -422-77
-499
>>> 4**5
1024
>>> 8/3
2
>>> 8.0/3.0
2.6666666666666665
>>> 8%3
2
>>> 45L*25L
1125L
>>> 0x80+0777
639
>>> 0+1j**2
(-1+0j)
5.5.4 位操作符(只适用于整型)
python整型支持标准位运算:
取反(~),按位与(&)、或(|)、异或(^)、左移(<<)右移(>>)
负数会被当做正数的2进行制补码处理
左移和右移N位等同于无溢出检查的2的N次幂运算:2**N
>>> 30&45
12
>>> 30|45
63
>>> 30&30
30
>>> 30|30
30
>>> ~30
-31
>>> ~45
-46
>>> 45<<22
188743680
>>> 45<<1
90
>>> 30^2
28
5.6 内建函数与工厂函数
5.6.1 标准类型函数
>>> cmp(-6,2)
-1
>>> cmp(0xFF,255)
0
>>> type('int')
<type 'str'>
>>> type(2-1j)
<type 'complex'>
5.6.2 数字类型函数
1.转换工厂函数
函数int()、long()、float()、complex()用来将其他数值类型转换为响应的数值类型。
>>> int(4.25555)
4
>>> long(42)
42L
>>> float(4)
4.0
>>> complex(4)
(4+0j)
>>> complex(2.4,-8)
(2.4-8j)
>>> complex(2.3e-10,45.3e4)
(2.3e-10+453000j)
2.功能函数
python有5个运算内建函数用于数值运算:abs()、coerce()、divmod()、pow()、round()
abs()返回给定参数的绝对值。若参数为复数,则返回math.sqrt(num.real2+num.imag2)
>>> abs(-1)
1
>>> abs(-10.)
10.0
>>> abs(1.2-2.1j)
2.4186773244895647
coerce()返回一个包含类型转换的完毕的两个元素的数值元素的元组。
>>> coerce(1,2)
(1, 2)
>>> coerce(1.3,134L)
(1.3, 134.0)
>>> coerce(1j,134L)
(1j, (134+0j))
divmod()内建函数把除法一求余结合起来,返回一个包含商和余数的元组。
>>> coerce(1j,134L)
(1j, (134+0j))
>>> divmod(10,3)
(3, 1)
>>> divmod(3,10)
(0, 3)
>>> divmod(2.5,10)
(0.0, 2.5)
>>> divmod(2+1j,0.5-1j)
((-0+0j), (2+1j))
pow()和(**)都可以进行指数操作,只是前者是内建函数,后者是操作符
>>> pow(2,5)
32
>>> pow(3.1415,4)
97.39760017099509
>>> pow(1+1j,3)
(-2+2j)
round()用于对浮点型进行四舍五入运算
>>> round(3)
3.0
>>> round(3.4444)
3.0
>>> round(3.4999999,1)
3.5
>>> round(3.449999)
3.0
- 函数int()直接截取小数部分(返回值为整型)
- 函数floor()得到最接近原数的但小于原数的整型(返回值为浮点型)
- 函数round()得到最接近原数的整型(返回值为浮点型)
5.63 仅用于整型的函数
1.进制转换函数
python支持八进制和十六进制,分别用内建函数oct() hex()来返回字符串
>>> hex(255)
'0xff'
>>> oct(255)
'0377'
2。ASCII转换函数
python提供了ASCII码与其序列值之间的转换函数。每个字符对应一个唯一的整型。
函数char()接受一个单字节整型值,返回一个字符串;函数ord()接受一个字符,返回其对应的整型值。
>>> chr(88)
'X'
>>> chr(44L)
','
>>> ord('g')
103
>>> ord('D')
68
5.7 其他数字类型
5.7.1 布尔“数”
布尔值事实上是整型的子类,对应与整型的1和0
有关布尔类型的概念:
- 有两个永不改变的True和False
- 布尔型是整型的子类,但不能再被继承而生成它的子类。
- 对于值为零的任何数字或空集在python中的布尔值都是False
- 数学运算中,Boolean值的True和False分别对应为1和0
#intro
>>> bool(1)
True
>>> bool(0)
False
>>> bool('1')
True
>>> bool('0')
True
>>> bool([])
False
#使用布尔数
>>> foo=42
>>> bar=foo<100
>>> bar
True
>>> print bar+100
101
>>> print '%s' % bar
True
>>> print '%d' % bar
1
5.7.2 十进制浮点型
通过字符串或其他的十进制数创建十进制浮点数。必须导入decimal模块以便于使用Decimal类
>>> from decimal import Decimal
>>> dec Decimal(.1)
SyntaxError: invalid syntax
>>> dec=Decimal(.1)
>>> dec
Decimal('0.1000000000000000055511151231257827021181583404541015625')
>>> print dec
0.1000000000000000055511151231257827021181583404541015625
>>> dec=Decimal('.1')
>>> dec
Decimal('0.1')
>>> print dec
0.1
5.8相关模块
对数字科学计算应用来说,有第三方包(Numeric(Numpy))和Scipy
声明:
以上学习笔记来自
《python核心编程》第2版 Wesley J.Chun 编著 宋吉广译 人民邮电出版社
发表评论