手记

笔记_Python3学习笔记(n2.2:对象类型

嵌套允许直接并轻松的建立复杂的信息结构,使用C这样的底层语言写同样的程序,C语言更枯燥的使用更多代码。Python中,这一切都是自动完成的,这是Python的优点之一。

同样道理底层语言中,我们不在需要该对象时,必须小心地释放掉所有对象空间。Python中当最后一次引用对象后这个对象所占用的内存空间将会自动清理掉:

>>>rec = 0
键的排序:for循环

字典不是序列,他们并不是包含任何可靠的从左至右的顺序。这一意味着,如如果我们建立一个字典,并将他们打印出来,它的键也许会以与我们输入时不同的书序出现(3.0版本会时出现。而我是3.6版本,所以自动排序):

>>> D = {'a': 1,'b': 2,'c': 3}
>>> D
{'a': 1, 'b': 2, 'c': 3}

在Python3.0版本中排序,常用解决办法是通过字典的K eys方法搜集一个键的列表,使用sort方法进行排序,然后使用Python的for循环逐个显示结果。

确保在循环的代码下面两次按下Enter键,交互模式中的空行一位置"执行"


>>> D = {'a':1,'b':2,'c':3}
>>> Ks = list(D.keys())        #无序列的列表o(>ω<)o
>>> Ks
['a', 'b', 'c']
>>>
>>> Ks.sort()                        #按升序排序
>>> Ks
['a', 'b', 'c']
>>>        #">>>"也是一个提示符
>>> for key in Ks: #key不是一个模块,他的命名是随意的,你可以把他们做一个变量
...     print(key,'=>',D[key])
...    #某些端口的提示符是"...",比如CMD、终端启动。
a => 1
b => 2
c => 3
>>>

当我们才用PYthon的对象是持久化时(在文件或键值数据保存在Python原生对象的简单方式),我们刚刚创建的rec记录,很有可能是数据库记录。这里我们不在深入讨论,你可以参考Python的pickle和shelve模块的细节。

在最近Python版本中通过使用最新的sorted内置函数可以一步完成。sorted调用返回结果并对各种对象类型进行排序在这个例子中,自动对字典的键排序:

>>> D
{'a': 1, 'b': 2, 'c': 3}
>>> for key in sorted(D):
    print(key,'=>',D[key])

a => 1
b => 2
c => 3

一个定义循环变量(这里key)用作每次运行过程中当前元素的参考量。例子的实际效果就是打印并排序键和值得顺序。

for循环和while循环其作用其相近,是脚本中编写重复性任务语句的主要方法。

for循环可以不仅循环字符串中的字符,打印每个字符的大写:

>>> for c in 'spam':
    print(c.upper())

S
P
A
M

while循环是一种更为常见的循环工具,他不仅限于遍历序列:

>>> x =4
>>> while x > 0:
    print('spam' * x)
    x -= 1

spamspamspamspam
spamspamspam
spamspam
spam

在稍后讨论循环语句。

迭代和优化

这是Python中无处不在的一个概念,表示内存中物理储存的序列,或一个在迭代操作情况下每次产生一个元素的对象,稍后介绍迭代协议,我写完后我需要写一个代码整合的笔记,然后背单词。

像下面这样的任何列表解析表达式都可以计算一列数字的平方:

>>> squares = [x**2 for x in [1,2,3,4,5]]
>>> squares
[1, 4, 9, 16, 25]

能够编写成一个for循环,通过在运行时手动添加列表来创建最终的列表:


>>> squares = []
>>> for x in [1,2,3,4,5]:
    squares.append(x ** 2)

>>> squares
[1, 4, 9, 16, 25]

尽管这一年噶列表解析和相关的函数编程工具,如map和filter,通常运行的比for循环快(也许快两倍):这是对有大数据集合的程序有重大影响的特性之一。在Python中 性能测试是一个很难应付的任务,因为他在反复地优化,也许版本和版本差异很大。

Python主要原则就是,首先为了简单和可读性去编写代码,在程序可以工作,并证明了确实有必要考虑性能后,在考虑问题。更多情况是的代码本身就已经足够快了。如果确实需要提高代码的性能,那么Python提供了帮助你实现的工具,包括time以及timeit模块和profile模块。

不存在的键:if测试

尽管我们能够通过给新的键复制来扩展字典,但是扩区一个不存在的键仍然是一个错误。

>>> D
{'a': 1, 'b': 2, 'c': 3}

>>> D['e'] = 99
>>> D
{'a': 1, 'b': 2, 'c': 3, 'e': 99}
>>> D['f']
Traceback (most recent call last):
  File "<pyshell#99>", line 1, in <module>
    D['f']
KeyError: 'f'

获取一个并不是存在的东西往往是一个错误。
我们编写程序时并不是总知道当前存在什么键。一个技巧就是首先进行测试
in关系变大时允许我们查询字典中的一个键是否存在,并可以通过if语句对结果进行分支处理(就像for一样,取保在这里两次按下Enter键来交互地运行id):

>>> 'f' in D                #真假表达式
False
>>> if not 'f' in D:        #稍后会介绍详细if
    print('missing')

missing

这里的表达方式很直接,(一般情况下测试指令是Python使用不到的,因为其他IDLE直接显示数据类型,自动加括号等,我喜欢文本编辑器的简洁界面但不实用)

这里有其他方法创建字典并避免获取不存在的字典键:get方法(带有一个默认值的条件索引)、PYthon2.X的has_key方法(在Python3.0中不可用)、try语句(一个捕获异常并从异常中恢复的工具,在后面会介绍),以及if/else表达式(实质上是挤在一行中的一条if语句)下面是一些例子:

>>> value = D.get('x',0)
>>> value
0
>>> value = D['x'] if 'x' in D else 0
>>> value
0

这里省略了细节留给了后边章节。

元组

元组对象(tuple,发音为"toople"或"tuhple")基本上就像一个不可以改变的列表一样,元组是序列,但他们具有不可变性,和字符串类似。从语法上将,他们编写在圆括号中而不是U方括号中,可以支持任意类型、任意嵌套以及常见的序列操作:

>>> T = (1,2,3,4)        #4项元组
>>> len(T)                    #长度(length)
4
>>> T + (5,6)                #Concatenation
(1, 2, 3, 4, 5, 6)
>>> T[0]
1

concatenation
Py3中元组有两个可调用方法:

>>> T.index(4)        #元组方法:4出现在偏移3
3
>>> T.count(4)        #4出现一次
1

元组一旦创建就不能再改变,元组是不可变的序列。

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

与列表和字典一样,元组支持混合类型和嵌套,但不能增长短,因为他们是不可变的:

>>> T = ('spam',3.0,[11,22,33])
>>> T[1]
3.0
>>> T[2][25]
22
>>> T.append(4)
Traceback (most recent call last):
为什么要元组

元组是可以说类似列表的类型,支持操作很少。
元组提供了一种完整性的约束,这对于我们这里所编写的更大型的程序来说是方便的。我们将会在稍后部分了解更多元组内容,现在直接学习最后一个核心类型-------文件

文件

文件对象是Python代码对电脑上外不文件的主要接口。文件是核心类型,没有特定语法常量创建文件。


>>> f = open ('data.txt','w')    #调用open函数以字符串形式传递给一个外部文件名以及一个处理模式的字符串。这个文件传递名为'w'
>>> f.write('Hello\n')            #返回字节数(直译)
6
>>> f.close()                        #接近冲洗输出缓冲区写入磁盘(直译)

写入 write
打开 open (直译)
关闭 close

在当前文件夹下创建一个文件并写入文本(文件名可以是完整的路径)。

以'r'处理模式打开文件,读取输入(调用时忽略模式的话,这将是默认的)。之后将内容读至一个字符串并显示。

对脚本而言没文件的内容总是字符串,无论文件包括的数据是什么类型。


>>> f = open('dadt.txt')        #'r'模式默认处理方式
>>> text = f.read()                #读入整个文件读取字符串
>>> text
'Hello\nworld\n'                    

>>> print(text)                         #打印以解释字符串
Hello
world

>>> text.split()                     #一个文件的内容始终是字符串
[ 'Hello', 'world']

这里对其他的文件对象方法支持特性不进行讨论。例如:文件对象提供方多种读和写的方法(read额可以接受一个字节大小的选项,readline每次读一行等),以及其他的工具(seek移动到一个新的文件位置)。我们在后面会看到,如今读取一个文件最佳方法就是根本不读它,文件提供了一个迭代器(iterator),他在for循环或其他环境中自动地一行一行地读取。


我们可以通过dir调用和在返回的任何地方用help来速览一个完整列表。

>>> dir(f)
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'writelines']
>>> help(f.seek)
太长省略了。。。。。

在后面还会看到Pythom3文件在文本和二进制数据之间化出一条清晰的界限。文本文件半额金融显示为字符串,并且自动执行Unicode编码和解码;而二进制文件把内容显示为一个特定的字节字符串类型,并且你不修改地访问文件内容:

>>> data = open('data.bin','rn').read()
>>>data
b'\x00\x00\x00\x07spam\x00\x08'
data[4:8]
b'spam'

如果你只处理ASCII文本的话,通常不需要关系这一却别,尽管如此,如果你处理国际化的应用程序或者面向字节的数据,Python3的字符串和文件是很有用的。

其他文件类工具

open函数能够实现在Python中编写的绝大多数文件处理。
对于更高级的任务Python还有额外的类文件工具:管道、先进的队列(FIFO)、套接字、通过键访问文件、对象持久、基于描述的文件、关系数据库和面向对象数据库接口等。例如,描述符文件(descriptor file)支持文件锁定和其他的底层工具,而套接字提供网络和进程间通信的接口。后面不全部介绍这些话题,但在开始使用Python编程时,一定会发现这些都很有用。

其他核心类型

集合是最近几年增加到这门语言中的类型,他不是映射也不是序列,相反,他们是唯一的不可变对象的无序集合。集合可以通过调用内置的set函数而创建,或者用Python3中新的集合常量和表达式创建,并且它支持一般的数字集合操作:

>>> X =set('spam')
>>> Y= {'h','a','m'}
>>> X,Y
({'a', 's', 'p', 'm'}, {'h', 'a', 'm'})

>>> X&Y            #Intersection
{'a', 'm'}

>>> X | Y            #操作符
{'h', 'm', 'a', 'p', 's'}

>>> X- Y            #差异
{'s', 'p'}

>>> {x** 2 for x in [1,2,3,4]}        #set comprehensions in 3.0
{16, 1, 4, 9}

Python新增加了一些新的数值类型:十进制(固定精度浮点数)和分数(有一个分子和一个分母的有理数)。他们都用来解决浮点数学的局限性和内在不精确性:

>>> 1/3            #Python2.6全精度数值
0.3333333333333331
>>> import decimal                #小数固定精度
>>> d = decimal.Decimal('3.141')
>>> d + 1
Decimal('4.141')
>>> from fractions import Fraction        #一个带分子和分母的分数
>>> f = Fraction (2,3)
>>> f + 1
Fraction(5, 3)
>>> f + Fraction (1,2)
Fraction(7, 6)

布尔值(又叫逻辑型)
True为真,False为假
实际上是定之后以逻辑型显示整数1和0,你可以试试True+False

>>> 1>2, 1<2
(False, True)
>>> bool('spam')
True

>>> X = None
>>> print(X)
None
>>> L = [None] * 100
>>> L
[这里省略]
如何破坏代码灵活性

稍后将对所有这些对象进行介绍。
内置函数type返回的类型对象是赋值给该对象,2.6和3.0结果有些不同,因为类型和类完全结合起来了。

>>> type(L)
<type 'list'>
>>> type(type(L))            #Python2.6
<type 'type'>
>>> 
>>> type(L)                    #Python3.0
<class 'list'>            
>>> type(type(L))
<class 'type'>
>>> 

除了探究对象,这个函数是应用是允许编写代码检查所处理的对象类型:

>>> if type (L) == type ([]):
    print ('yes')

yes
>>> if type (L) == list:
    print ('yes')

yes
>>> if isinstance(L,list):
    print('yes')

yes
用户自定义类

他可以通过支持程序定制而节省开发时间,这是真语言很强大的特性。

class Worker:
    def _init_(self,name,pay):
          self.name = name
                      self.pay = pay
    def lastName(self):
                      return self.name.split()[-1]
                def giveRaise (self,percent):
                      selfpay *= (1.0 + percent)

这个类定义了一个新的对象种类,属性有时叫做状态信息,也有两个小的行为编写为函数(通常叫做方法)的形式。就像那样去调用类,会生成我们新类型的实例,并且类的方法调用时,类的方法自动获取被处理的实例(其中的self参数):

#IDLE下运行
bob = Worker('Bob Smith',50000)
sue =  Worker('Sue Jones', 60000)
bob.lastName()
sue.lanstName()
sue.giveRaise(.10)
sue.pay

"self"对象使我们把这叫做面向对象模型的原因,以后会写。

代码笔记正在补充中

0人推荐
随时随地看视频
慕课网APP