Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5783556
  • 博文数量: 291
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 7924
  • 用 户 组: 普通用户
  • 注册时间: 2016-07-06 14:28
个人简介

阿里巴巴是个快乐的青年

文章分类

全部博文(291)

文章存档

2018年(21)

2017年(4)

2016年(5)

2015年(17)

2014年(68)

2013年(174)

2012年(2)

分类: Python/Ruby

2013-03-12 23:25:27

一、标识符与关键字

        有效的Python标识符是任意长度的非常字符列表,其中包括一个“引导字符”以及0个或多个“后续字符”。Python标识符必须符合两条规则,并遵循某些约定。

        第一条规则是关于引导字符与后续字符的。只要是Unicode编码的字母,都可以充当引导字符,包括ASCII字母、下划线以及大多数非英文语言的字母。后续字符可以是任意引导字符,或任意非空格字符,包括Unicode编码中认为是数字的任意字符,或者是加泰罗尼亚字符。标识符是大小写敏感的。

        第二条规则是Python标识符不能与Python关键字同名,因此,不能使用表1中的这些关键字作为标识符的名称。

                        表1 Python关键字

and
continue
except
global
lambda
pass
while
as
def
False
if
None
raise
with
assert
del
finally
import
nonlocal
return
yield
break
elif
for
in
not
True

class
else
from
is
or
try


        第一条约定是不要使用Python预定义的标识符名对自定义的标识符进行命名。Python有一个内置函数dir(),可以返回对象属性列表,不带参数调用该函数时,将返回Python内置属性列表,也可以以其返回值即内置属性作为其参数。

        第二条预定是关于下划线(_)的使用,应该避免在名的开头和结尾都使用下划线,这是因为其与Python定义的各种特殊方法与变量冲突。

        说一千道一万,就是不要使用生僻或怪异的名称,因为这样可能会产生潜在的问题。


二、Integral类型

        Python提供了两种内置的Integral类型,即int与bool。在布尔表达式中,0与False表示False,其它任意整数与true都表示true。在数字表达式中,True表示1,False表示0。这意味着用表达式i += True来对整型变量i进行递增操作也是合法的。

1、整数

        整数的大小只受限于机器内存大小,默认使用十进制,也可以使用其它进制,例如:二进制数以0b引导,八进制数以0o引导,十六进制数则以0x或者0X引导。

        所有常见的数学函数与操作符都可用于整数。整数转换函数包括bin(i)、hex(i)、int(x)、int(s, base)、oct(i)。

2、布尔型

        有两个内置的布尔型对象:True与False。


三、浮点类型

        Python提供了3中浮点值:内置的float与complex类型,以及来自标准库的decimal.Decimal类型。

1、浮点数       

        float类型存放双精度的浮点数,取值范围依赖于构建Python的C(或者C#或Java)编译器,其数值使用小数点或指数表示。

        float类型精度不高,如果需要高精度浮点数则可以使用来自decimal模块的decimal.Decimal数,默认情况下到小数点后28位。

        Python支持混合模式的算术运算,比如:使用int与float运算生成float数;使用float与complex运算生成complex数;但是decimal.Decimal只能与decimal.Decimal或者intS运算生成decimal.Decimal数;不兼容的数据类型进行运算会产生TypeError异常。

2、复数

        复数存放的是一对浮点数,一个表示实数部分,另一个表示虚数部分,用+或者-将实数部分与虚数部分(其后跟随一个字母j)连接在一起共同构成复数。复数的两个部分都以属性名的形式存在,分别为real与imag,例如:

        >>> z = 1.2 + 7.2j

        >>> z.real, z.imag

        (1.2, 7.2)

        除了//、%、divmod()以及三个参数的pow()之外,所有数值类型操作符与函数都可用于对复数进行操作。复数提供一个方法conjugate()用于改变虚部的符号。

3、十进制数字

        十进制数使用decimal.Decimal()函数创建,该函数可以接受一个整数或字符串参数,但是不能以浮点数作为参数,因为浮点数不够精度,decimal则很精确。要创建Decimal,必须先导入decimal模块。

        从Python3.1开始,使用decimal.Decimals from-float()函数能将floasts转换为十进制数,该函数以float型数为参数,并返回与该float数值最为接近的decimal.Decimal。

        大多数数值类型操作符与函数都可用于decimal.Decimals,但是有两个约束:如果操作符左边的操作数为decimal.Decimal,那么其右边的操作数必须为整数;同样地,如果pow()函数的第一个参数为decimal.Decimal,那么其第二个以及可选的第三个参数必须为整数。


四、字符串

        字符串使用str数据类型表示,其中存放Unicode字符序列。字符串可以使用单引号、双引号、三引号,但是字符串两端必须相同。如果引号包含的字符串中又含有引号,则内层引号与外层引号相同时,需要转义内存引号,内存引号与外层引号不相同时,则可以直接使用该引号,例如:

        a = "hello 'li lei', fine, think you!"

        b = 'hello \'li lei\', fine, think you!'

        Python使用换行作为其语句终结符,但是如果在圆括号内、方括号内、花括号内或三引号包含的字符串内则是例外。

        有些情况下,比如,编写正则表达式时,需要创建带有大量字面意义反斜杠的字符串,由于需要对每个反斜杠进行转义处理,从而造成不便,解决方案是用字面意义的r引导字符串,这种字符串内部的所有字符都按其字面意义理解,而不再需要进行转义。

        当字符串比较长时,建议用圆括号将跨越多行的任何语句进行封装,而不是用转义的换行符。

1、比较字符串

        Python使用Unicode字符串,因此,比较字符串时存在两个问题(这不是Python特有的问题):

        (1)有些Unicode字符可以用两种或更多种字节序列表示,需要对其进行编码才能解决此问题。

        Python导入unicodedata模块,并以NFKD(标准化的方法即Normalization Form Compatibility Decomposition)为第一个参数调用unicodedata.normalize(),则返回以UTF-8编码字节表示的字节序列。

        (2)字符排序特定于某种语言(瑞典语、德语、丹麦语等)。

        Python使用字符串的内存字节表示,排序基于Unicode字元,也可以自定义排序方法。

2、字符串分片与步距

        提取操作符[]不仅可以提取单个数据项或者单个字符,还能提取数据项或字符的整个分片(子序列),在这种情况下提取操作符被用作分片操作符。字符串正索引位置从0开始到字符串长度减1,负索引位置-1总是代表字符串的最后一个字符,存取超出范围的索引位置(或空字符串中的索引位置)会产生IndexError异常。

        分片操作符有3中语法格式,seq可以使任意序列,比如:列表、字符串或元组,start、end与step都必须是整数,具体如下:

        (1)seq[start]

        提取序列从start开始的数据项。

        (2)seq[start:end]
        提取序列从start开始到end结束的数据项(不包含)。如果忽略起点索引值,则默认为0,如果忽略终点索引,则默认为len(seq),如果同时忽略两个索引值,则与s[0:len(s)]等价,即提取整个序列。

        (3)seq[start:end:step]
        从start开始到end结束每隔step个字符进行提取。如果忽略起点索引值,则默认为0,除非给定负的step值,则此时索引值默认为-1,如果忽略终点索引值,则默认为len(seq),除非给点负的step值,则此时终点索引值默认为字符串起点前面。不能忽略step,且step不能为0。step为-1意味着每个字符都将被提取,而且方向为从终点到起点,即产生反转字符串。
3、字符串操作符与方法
        所有能用于固定序列的操作都可用于字符串,包括in、+=、*、*=等。此外,还有很多字符串方法,包括取子串、大小写转换、字符串分割、模式匹配、格式化、编码、字符值判断、反转、连接等。
        字符串的操作中,+操作被重载用于实现字符串连接,但是如果需要连接大量的字符串,使用str.join()方法是一种更好的方案。该方法以一个序列作为参数,用str作为分隔符,将序列中的字符串用分隔符连接起来,然后存放到一个单独的字符串中,例如:
        >>> test = ["I", "am", "shichangquan"]
        >>> " ".join(test)
        'I am shichangquan'
        >>> "--".join(test)
        'I--am--shichangquan'
        操作符*提供了字符串复制功能:
        >>> s1 = "="*5
        >>> print(s1)
        =====
        >>> s2 *= 10
        >>> print(s2)
        ==========
4、字符串格式化
        使用str.format()方法进行字符串格式化,该方法提供了非常灵活而强大的创建字符串的途径。str.format()方法会返回一个新字符串,在新字符串中,原字符串的替换字段被适当格式化后的参数所替代,例如:
        >>> "The novel '{0}' was published in '{}'".format("Hard Times", 1854)
        "The novel 'Hard Times' was published in 1854"
        每个替换字段都由包含在花括号中的字段名标识,如果字段名是简单的整数,就将被作为传递给str.format()方法的一个参数的索引位置,如上例中,名为0的字段被第一个参数所替代,名为1的字段则被第二个参数所替代。
        替换字段可以使用下面的任意一种语法格式:
        {field_name}
        {field_name!conversion}
        {field_name:format_specification}
        {field_name!conversion:format_specification}
        另外需要注意的一点是,替换字段本身也可以包含替换字段,嵌套的替换字段不能有任何格式,其用途主要是格式化规约的计算,下面是一些例子:
        >>> "{who} turned {age} this year".format(who="She", age=88)
        'She turned 88 this year'
        >>> "The {who} was {0} last week".format(12, who="boy")
        'The boy was 12 last week'
        >>> stock = ["page", "envelopes", "notepads", "pens", "paper clips"]
        >>> "We have {0[1]} and {0[2]} in stock".format(stock)
        'We have envelopes and notepads in stock'
        >>> d = dict(animal="elephant", weight=12000)
        >>> "The {0[animal]} weights {0[weight]}kg".format(d)
        'The elephant weights 12000kg'
        >>> "math.pi=={0.pi} sys.maxunicode=={1.maxunicode}".format(math, sys)
        'math.pi==3.14159265359 sys.maxunicode==65535'
        >>> "{} {} {}".format("Python", "can", "count")
        'Python can count'
        上面的例子不过多解释,看了就会心领神会。
        下面介绍一种“诡异”的技术:当前还在作用范围内的局部变量可以通过内置的locals()函数访问,该函数会返回一个字段,字段的键是局部变量名,字典的值则是对变量值的引用。现在,我们可以使用映射拆分将该字段提供给str.format()方法,映射拆分操作符为**,可应用于映射(比如字典)来产生一个适合于传递给函数的键-值列表,例如:
        >>> element = "Silver"
        >>> number = 47
        >>> "Element {number} is {element}".format(**locals())
        'Element 47 is Silver'
        对于字符串而言,可以控制的包括填充字符、字段内对齐方式以及字段宽度的最小值与最大值。字符串格式规约是使用冒号(:)引入的,其后跟随可选的字符对——一个填充字符(可以不是))与一个对齐字符(<用于左对齐,^用于中间对齐,>用于右对齐),之后跟随的是可选的最小宽度(整数),如果需要制定最大宽度,就在其后使用句点,句点后跟随一个整数值。
        注意locale.setlocale()不是thread-safe的。
5、字符编码
        本质上说,计算机只能存储字节,即8比特的值,如果是无符号数,那么取值范围从0x00到0xFF,每个字符必须都以某种形式的字节表示。但是由于各种原因导致实际编码种类非常多,这对编写国际化软件非常不利,而Unicode编码的出现解决了这个问题。
        Unicode为每个字符分配一个整数,即字元,Unicode不局限于使用一个字节表示每个字符,为了更好的兼容性,其中前127个Unicode字符与7比特ASCII表示的前127个字符是相同的。在内存中,Unicode通常以UCS-2格式(实质上是16比特的无符号整数)表示前65535个字元,或者以USC-4格式(32整数)表示所有的字元。在Python编译时,会设置为使用某一种格式(如果sys.maxunicode为65535,Python编译时就是用UCS-2)。
        对于存放在文件中或通过网络连接传送的数据,情况会更加复杂。如果使用了Unicode,那么字元可以使用UTF-8进行编码——这种编码中,对前127个字元,每个字符使用一个字节表示;对其它字元,则使用两个或更多的字节数来表示每个字符。对于英文文本而言,UTF-8是非常紧凑的,如果只使用了7个比特字符,则UTF-8文件与ASCII文件实质上是一样的。另一种常见的编码方式是UTF-16编码,这种编码方式中,对大多数字符使用两个字节表示,对其它的一些字符则使用4个字节表示。对某些亚洲语言,这种编码方式比UTF-8更紧凑,但与UTF-8不同的是,UTF-16文本应该以一个字节顺序标记开始,以便用于读取该文本的代码可以判定字节对是big-endian还是little-endian。此外,所有旧的编码格式,比如GB2312、ISO-8859-5、Latin-1等,实际上都在常规的使用中。
        str.encode()方法可以返回一个字节序列——实际上是一个bytes对象,在编码时根据提供的编码参数进行编码。使用这一方法,可以更好地理解不同编码格式之间的差别,以及为什么进行错误的编码假设或导致错误。这个方法的第一个参数为必选参数用于指定编码,第二个参数为可选参数用于指定错误处理方式。该方法的具体信息后文书还会详解,或者参考Python文档。
        Python的.py文件使用UTF-8编码,因此,Python总是知道字符串字面值要使用的编码格式。这意味着,我们可以在字符串中输入任意的Unicode字符——只要使用的编辑器支持。在从外部源(比如socket)读取数据时,Python无法知道其使用的编码格式,因此会返回字节序列,并由程序员对其进行相应的解码。对文本文件,Python采用一种更软化的方法,即使用本地编码——除非明确指定编码格式。
       幸运的是,有些文件格式会指定其编码格式,比如:XML文件默认使用的就是UTF-8编码,除非指令明确地指定了不同的编码格式,则需要先提取比如前1000个字节以寻找其中的编码规约,如果找到,则使用指定格式解码。Python提供了用于检测文件编码格式的包,具体可以参看Python文档。

阅读(3996) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~

scq2099yt2013-04-07 22:11:43

ning_lianjie:良好的基础知识记录,最好给关键字加上注释.

谢谢建议

回复 | 举报

ning_lianjie2013-04-07 21:49:19

良好的基础知识记录,最好给关键字加上注释.

scq2099yt2013-03-16 22:44:02

文明上网,理性发言...