Size: 9078
Comment:
|
Size: 31426
Comment: 数据类型
|
Deletions are marked like this. | Additions are marked like this. |
Line 3: | Line 3: |
== 附录 —— 有选择性的让人印象深刻的 python 简短回顾 == | == 附录 —— 选择性的令人印象深刻的 python 简短回顾 == |
Line 6: | Line 6: |
------------------------------------------------------------------- | |
Line 56: | Line 56: |
=== 第一节 —— python 属于哪种类型的语言 === | === python 属于哪种类型的语言 === |
Line 58: | Line 58: |
-------------------------------------------------------------------- | `--------------------------------------------------------------------` |
Line 111: | Line 111: |
=== 第二节 —— 名字空间与绑定 === | === 名字空间与绑定 === |
Line 114: | Line 114: |
-------------------------------------------------------------------- | `--------------------------------------------------------------------` |
Line 142: | Line 142: |
==== 赋值和解除引用 ==== TOPIC -- Assignment and Dereferencing `--------------------------------------------------------------------` A Python statement like 'x=37' or 'y="foo"' does a few things. If an object--e.g., '37' or '"foo"'--does not exist, Python creates one. If such an object -does- exist, Python locates it. Next, the name 'x' or 'y' is added to the current namespace, if it does not exist already, and that name is bound to the corresponding object. If a name already exists in the current namespace, it is re-bound. Multiple names, perhaps in multiple scopes/namespaces, can be bound to the same object. 像 'x=37' 或 'y="foo"' 这样的 python 表达式干了好几件事。 如果该对象—— 比如说 '37' 或是 '"foo"' ——不存在,python 就创建一个。 如果该对象存在,python 则定位到它。 然后,如果名字 'x' 或 'y' 不存在的话,就会被加到当前的名字空间中, 并且这个名字被绑定到相应的对象。如果当前名字空间中该名字已经存在,它就被重新绑定。 多个名字,可能还在多个作用范围/名字空间中,都可以绑定到同一个对象。 A simple assignment statement binds a name into the current namespace, unless that name has been declared as global. A name declared as global is bound to the global (module-level) namespace instead. A qualified name used on the left of an assignment statement binds a name into a specified namespace--either to the attributes of an object, or to the namespace of a module/package, for example: 一个简单的赋值语句会将一个名字绑定到当前的名字空间中,除非该名字已经被声明成 global 了。 一个定义为 global 的名字被绑定到全局 (模块级) 名字空间中。 在赋值语句左边出现的受限名字 (qualified name) 将一个名字绑定到一个指定的名字空间——可能是对象的属性,或是模块/包的名字空间, 比如: {{{#!python >>> x = "foo" # bind 'x' in global namespace >>> def myfunc(): # bind 'myfunc' in global namespace ... global x, y # specify namespace for 'x', 'y' ... x = 1 # rebind global 'x' to 1 object ... y = 2 # create global name 'y' and 2 object ... z = 3 # create local name 'z' and 3 object ... >>> import package.module # bind name 'package.module' >>> package.module.w = 4 # bind 'w' in namespace package.module >>> from mymod import obj # bind object 'obj' to global namespace >>> obj.attr = 5 # bind name 'attr' to object 'obj' }}} {{{#!python >>> x = "foo" # 将 'x' 绑定到全局名字空间 >>> def myfunc(): # 将 'myfunc' 绑定到全局名字空间 ... global x, y # 为 'x', 'y' 指定名字空间 ... x = 1 # 将全局名字 'x' 重绑定到对象 1 ... y = 2 # 创建全局名字 'y' 和对象 2 ... z = 3 # 创建局部名字 'z' 和对象 3 ... >>> import package.module # 绑定名字 'package.module' >>> package.module.w = 4 # 将 'w' 绑定到名字空间 package.module >>> from mymod import obj # 将对象 'obj' 绑定到全局名字空间 >>> obj.attr = 5 # 将名字 'attr' 绑定到对象 'obj' }}} Whenever a (possibly qualified) name occurs on the right side of an assignment, or on a line by itself, the name is dereferenced to the object itself. If a name has not been bound inside some accessible scope, it cannot be dereferenced; attempting to do so raises a 'NameError' exception. If the name is followed by left and right parentheses (possibly with comma-separated expressions between them), the object is invoked/called after it is dereferenced. Exactly what happens upon invocation can be controlled and overridden for Python objects; but in general, invoking a function or method runs some code, and invoking a class creates an instance. For example: 无论何时一个名字(可能是受限的)出现在赋值语句的右边,或者在只有它自己的行中, 该名字都会被解除引用而得到它引用的对象。 如果一个名字没有被绑定到某个可访问的作用范围里面,它就不能被解除引用; 如果试图这样做的话会抛出一个 'NameError' 的异常。如果名字后面跟着左右两个括号 (其中可能还有逗号分割的表达式), 在解除引用后,该对象会被调用。调用期间实际干些什么事情可以被 python 对象控制和重写。 不过通常调用一个函数或方法会执行一些代码,调用一个 class 会创建一个实例。 比如: {{{#!python >>> pkg.subpkg.func() # invoke a function from a namespace >>> x = y # deref 'y' and bind same object to 'x' }}} {{{#!python >>> pkg.subpkg.func() # 从一个名字空间中调用一个函数 >>> x = y # 对 'y' 解除引用并绑定该对象给 'x' }}} ==== 函数和类的定义 ==== TOPIC -- Function and Class Definitions `--------------------------------------------------------------------` Declaring a function or a class is simply the preferred way of describing an object and binding it to a name. But the 'def' and 'class' declarations are "deep down" just types of assignments. In the case of functions, the `lambda` operator can also be used on the right of an assignment to bind an "anonymous" function to a name. There is no equally direct technique for classes, but their declaration is still similar in effect: 定义一个函数或类简直是描述一个对象并将它绑定到一个名字的首选方式了。 不过 'def' 和 'class' 声明本质上 (deep down) 只是赋值的不同形式罢了。 拿函数来说,我们还可以在赋值语句的右边使用'lambda' 运算符,这样可以绑定一个“匿名”函数到一个名字。 对于类来说没有和它等价的便捷技术,不过在效果上它们的声明还是很相似的: {{{#!python >>> add1 = lambda x,y: x+y # bind 'add1' to function in global ns >>> def add2(x, y): # bind 'add2' to function in global ns ... return x+y ... >>> class Klass: # bind 'Klass' to class object ... def meth1(self): # bind 'meth1' to method in 'Klass' ns ... return 'Myself' }}} {{{#!python >>> add1 = lambda x,y: x+y # 在全局名字空间中将 'add1' 绑定到函数 >>> def add2(x, y): # 在全局名字空间中将 'add2' 绑定到函数 ... return x+y ... >>> class Klass: # 将 'Klass' 绑定到类对象 ... def meth1(self): # 在 'Klass' 名字空间中将 'meth1' 绑定到方法 ... return 'Myself' }}} ==== 'import' 表达式 ==== TOPIC -- 'import' Statements `--------------------------------------------------------------------` Importing, or importing -from-, a module or a package adds or modifies bindings in the current namespace. The 'import' statement has two forms, each with a bit different effect. Statements of the forms: 导入——或者从某处导——一个模块或者一个包,会在当前名字空间中添加或修改一些绑定。 'import' 表达式有两种形式,每一种都有稍微不同的效果。 这种形式的表达式: {{{#!python >>> import modname >>> import pkg.subpkg.modname >>> import pkg.modname as othername }}} add a new module object to the current namespace. These module objects themselves define namespaces that you can bind values in or utilize objects within. 在当前名字空间中增加一个新的模块对象。 这些模块对象本身定义了名字空间,你可以绑定值到其中,也可以利用其中的对象。 Statements of the forms: 这种形式的表达式: {{{#!python >>> from modname import foo >>> from pkg.subpkg.modname import foo as bar }}} ...instead add the names 'foo' or 'bar' to the current namespace. In any of these forms of 'import', any statements in the imported module are executed--the difference between the forms is simply the effect upon namespaces. 则向当前名字空间添加名字 'foo' 或 'bar'。 'import' 表达式的任何一个形式中,被导入的模块中的所有表达式都会被执行——区别只在于对名字空间产生的效果。 There is one more special form of the 'import' statement; for example: 这是 'import' 表达式的一种更特殊的形式: {{{#!python >>> from modname import * }}} The asterisk in this form is not a generalized glob or regular expression pattern, it is a special syntactic form. "Import star" imports every name in a module namespace into the current namespace (except those named with a leading underscore, which can still be explicitly imported if needed). Use of this form is somewhat discouraged because it risks adding names to the current namespace that you do not explicitly request and that may rebind existing names. 这种形式中的星号不是一个通用形式的 glob 也不是正则表达式的模式,它是一个特殊的语法形式。 "Import star" 会将模块名字空间中的所有名字导入到当前名字空间中来 (除了那些以下划线开头的名字,如果需要的话它们也可以被显示地导入进来)。 我们不太提倡这种形式的 import ,因为它可能会添加一些你明显并不需要的名字到当前名字空间, 还可能重绑定已有名字。 ==== 'for' 表达式 ==== TOPIC -- 'for' Statements `--------------------------------------------------------------------` Although 'for' is a looping construct, the way it works is by binding successive elements of an iterable object to a name (in the current namespace). The following constructs are (almost) equivalent: 虽然 'for' 是用来建立循环的,不过它工作的方式是通过将一个可迭代 (iterable) 对象中的连续元素绑定到一个名字 (在当前名字空间中) 来完成的。以下语句是 (几乎) 等价的: {{{#!python >>> for x in somelist: # repeated binding with 'for' ... print x ... >>> ndx = 0 # rebinds 'ndx' if it was defined >>> while 1: # repeated binding in 'while' ... x = somelist[ndx] ... print x ... ndx = ndx+1 ... if ndx >= len(somelist): ... del ndx ... break }}} {{{#!python >>> for x in somelist: # 用 'for' 重复绑定 ... print x ... >>> ndx = 0 # 如果 'bdx' 定义过,则重绑定之 >>> while 1: # 在 'while' 中重复绑定 ... x = somelist[ndx] ... print x ... ndx = ndx+1 ... if ndx >= len(somelist): ... del ndx ... break }}} ==== 'except' 表达式 ==== TOPIC -- 'except' Statements `--------------------------------------------------------------------` The 'except' statement can optionally bind a name to an exception argument: 'except' 表达式可选地将一个名字绑定到一个异常参数上: {{{#!python >>> try: ... raise "ThisError", "some message" ... except "ThisError", x: # Bind 'x' to exception argument ... print x ... some message }}} {{{#!python >>> try: ... raise "ThisError", "some message" ... except "ThisError", x: # 将 'x' 绑定到异常参数上 ... print x ... some message }}} === 数据类型 === SECTION -- Datatypes `--------------------------------------------------------------------` Python has a rich collection of basic datatypes. All of Python's collection types allow you to hold heterogeneous elements inside them, including other collection types (with minor limitations). It is straightforward, therefore, to build complex data structures in Python. python 有一组丰富的基本数据类型。所有 python 的 collection 类型 都可以在其中包含不同类型的元素,甚至其它 collection 类型 (会稍微有点限制)。 因此,在 python 中构建复杂数据结构变得非常简单。 Unlike many languages, Python datatypes come in two varieties: mutable and immutable. All of the atomic datatypes are immutable, as is the collection type 'tuple'. The collections 'list' and 'dict' are mutable, as are class instances. The mutability of a datatype is simply a question of whether objects of that type can be changed "in place"--an immutable object can only be created and destroyed, but never altered during its existence. One upshot of this distinction is that immutable objects may act as dictionary keys, but mutable objects may not. Another upshot is that when you want a data structure--especially a large one--that will be modified frequently during program operation, you should choose a mutable datatype (usually a list). 和许多其他语言都不一样,python 的数据类型分为两种:可变的和不可变的。 所有原子数据类型都是不可变的数据类型,包括 collection 类型 'tuple' 也是属于这类的。 collection 数据类型 'list' 和 'dict' 是可变的,包括类、实例都是属于这一类的。 一个数据类型的可变性说的其实就是该类型的对象是否可以“就地”修改—— 不可变的对象就只能够对它们进行创建和销毁,不可能在它们存在的期间对它们进行修改。 这种区分导致的一个结果就是不可变对象可以作为字典的 key,而可变对象不能。 导致的另一个结果就是如果需要一个数据结构——特别是很大的数据结构—— 要在程序操作期间经常被修改,那你应该选择一个可变的数据结构(通常是一个 list)。 Most of the time, if you want to convert values between different Python datatypes, an explicit conversion/encoding call is required, but numeric types contain promotion rules to allow numeric expressions over a mixture of types. The built-in datatypes are listed below with discussions of each. The built-in function `type()` can be used to check the datatype of an object. 大部分时候,如果你想在不同 python 数据类型之间对值进行转换,需要显示地进行转换(或者说编码)调用,不过数值类型包含有 提升 (promotion) 规则,可以允许数值表达式中混合多种类型。下面列出所有内置数据类型和相关的讨论。 内置函数 `type()` 可以用来查看一个对象的类型。 ==== 简单类型 ==== TOPIC -- Simple Types `--------------------------------------------------------------------` bool Python 2.3+ supports a Boolean datatype with the possible values 'True' and 'False'. In earlier versions of Python, these values are typically called '1' and '0'; even in Python 2.3+, the Boolean values behave like numbers in numeric contexts. Some earlier micro-releases of Python (e.g., 2.2.1) include the -names- 'True' and 'False', but not the Boolean datatype. python 2.3 及其后续版本支持 Boolean 数据类型,只能取 'True' 和 'False' 两个值。 在 python 更早期的版本中,这些值被象征性地叫做 '1' 和 '0';甚至在 python2.3 及其后续版本中,Boolean 型值在数值环境中的行为也很像数字。有一些更早的 python micro-releases (比如 2.2.1) 中包含有名字 'True' 和 'False',不过不是 Boolean 数据类型 int A signed integer in the range indicated by the register size of the interpreter's CPU/OS platform. For most current platforms, integers range from (2**31)-1 to negative (2**31)-1. You can find the size on your platform by examining `sys.maxint`. Integers are the bottom numeric type in terms of promotions; nothing gets promoted -to- an integer, but integers are sometimes promoted to other numeric types. A float, long, or string may be explicitly converted to an int using the `int()` function. SEE ALSO, [int] 有符号整数的范围由解释器所处的 CPU/OS 平台的寄存器大小决定。 对目前大部分平台来说,整数的范围是从负 (2**31)-1 到正 (2**31)-1 。 你可以通过 `sys.maxint` 查看在你的平台上的大小。 按照提升 (promotion) 规则来说整数是最基础的数值类型; 没有东西可以被提升 (promotion) 为一个整数,但是整数有时候会被提升为其他数值类型。 浮点数、长整型,或者字符串都可以通过 `int()` 函数显式地转换成整数。 long An (almost) unlimited size integral number. A long literal is indicated by an integer followed by an 'l' or 'L' (e.g., '34L', '9876543210l'). In Python 2.2+, operations on ints that overflow `sys.maxint` are automatically promoted to longs. An int, float, or string may be explicitly converted to a long using the `long()` function. 这是个 (几乎) 没有大小限制的整数。 后面跟着一个 'l' 或 'L' 的整数表示一个长整数(比如 '34L', '9876543210l')。 python 2.2 及其后续版本中,在超过 `sys.maxint` 的整数上进行操作会自动提升为长整数。 整数、浮点数或字符串可以通过 `long()` 函数显式地转换为长整数。 float An IEEE754 floating point number. A literal floating point number is distinguished from an int or long by containing a decimal point and/or exponent notation (e.g., '1.0', '1e3', '.453e-12', '37.'). A numeric expression that involves both int/long types and float types promotes all component types to floats before performing the computation. An int, long, or string may be explicitly converted to a float using the `float()` function. SEE ALSO, [float] 这是 IEEE754 浮点数。浮点数于整数或长整数在字面上的区别在于包含了十进制的小数部分 和/或 指数符号(比如 '1.0', '1e3', '.453e-12', '37.')。一个同时涉及到 整数/长整数 和浮点数的数值表达式会将所有类型提升为浮点型,然后才进行计算。 整数、长整数或字符串都可以通过 `float()` 函数显式转换为浮点数。 complex An object containing two floats, representing real and imaginary components of a number. A numeric expression that involves both int/long/float types and complex types promotes all component types to complex before performing the computation. There is no way to spell a literal complex in Python, but an addition such as '1.1+2j' is the usual way of computing a complex value. A 'j' or 'J' following a float or int literal indicates an imaginary number. An int, long, or string may be explicitly converted to a complex using the `complex()` function. If two float/int arguments are passed to `complex()`, the second is the imaginary component of the constructed number (e.g., 'complex(1.1,2)'). 这是个包含两个浮点数的对象,分别表示数字中的实部和虚部。 同时涉及到 整数/长整数/浮点数 和复数的数值表达式会将所有类型都提升为复数然后才进行计算。 在 python 中没有用来表达复数的字面量 (literal), 不过像 '1.1+2j' 这样的加法常常用来计算一个复数。 在一个浮点数后面跟一个 'j' 或 'J' 表示一个虚数。 整数、长整数或字符串都可以通过 `complex()` 函数显式转换地为复数。 如果给 `complex()` 传递两个浮点型/整型参数,那么第二个将成为虚数部分。 string An immutable sequence of 8-bit character values. Unlike in many programming languages, there is no "character" type in Python, merely strings that happen to have length one. String objects have a variety of methods to modify strings, but such methods always return a new string object rather than modify the initial object itself. The built-in `chr()` function will return a length-one string whose ordinal value is the passed integer. The `str()` function will return a string representation of a passed in object. For example: 一个不可变的8位字符的序列。 不像许多其他编程语言,python 中没有字符型,只有长度为1的字符串。 字符串对象有许多方法可以用来修改字符串, 不过这些方法总是返回一个新的字符串对象, 而不是修改一开始那个。 内置函数 `chr()` 会返回一个长度为1的字符串,它的 ascil 码值为传入的整数。 `str()` 函数返回传入对象的字符串表现形式。比如: {{{#!python >>> ord('a') 97 >>> chr(97) 'a' >>> str(97) '97' }}} SEE ALSO, [string] unicode An immutable sequence of Unicode characters. There is no datatype for a single Unicode character, but unicode strings of length-one contain a single character. Unicode strings contain a similar collection of methods to string objects, and like the latter, unicode methods return new unicode objects rather than modify the initial object. See Chapter 2 and Appendix C for additional discussion, of Unicode. 一个不可变的 Unicode 字符序列。 没有表达单个 Unicode 字符的数据类型,不过长度为1的 unicode 字符串包含单个字符。 Unicode 字符串包含一组和字符串对象类似的方法,而且和后者一样, unicode的方法也是返回新的 unicode 对象,而非修改一开始那个。 第2章和 附录 C 中有更多 Unicode 的讨论。 |
附录 —— 选择性的令人印象深刻的 python 简短回顾
APPENDIX -- A Selective and Impressionistic Short Review of Python
- A reader who is coming to Python for the first time would be well served reading Guido van Rossum's _Python Tutorial_, which can be
downloaded from <http://python.org/>, or picking up one of the several excellent books devoted to teaching Python to novices. As indicated in the Preface, the audience of this book is a bit different.
第一次接触 python 的读者适合去读 GUIdo van Rossum 的 Python Tutorial, 可以从 http://python.org/ 下载, 或者选一本针对 python 初学者的好书。 就像序言中说过的那样,本书针对的读者会稍微不太一样。
- The above said, some readers of this book might use Python only infrequently, or not have used Python for a while, or may be sufficiently versed in numerous other programming languages, that a quick review on Python constructs suffices for understanding. This appendix will briefly mention each major element of the Python language itself, but will not address any libraries (even standard and ubiquitous ones that may be discussed in the main chapters). Not all fine points of syntax and semantics will be covered here, either. This review, however, should suffice for a reader to understand all the examples in this book.
上面说了,本书的读者也许只是不常使用 python,或是有一段时间没有过 python , 或是精通许多其它语言,对他们来说只要对 python 来一点简短的回顾他们就能懂了。 本附录将会简要地谈谈 python 语言本身的每一个重要组成部分,但不会涉及任何库
- (甚至是标准库和在本书主要章节中讨论的常用库)。也不会涉及到所有语法和语义的细节。
不过,这篇回顾应该足够让读者理解本书中所有例子了。
- Even readers who are familiar with Python might enjoy skimming this review. The focus and spin of this summary are a bit different from most introductions. I believe that the way I categorize and explain a number of language features can provide a moderately novel--but equally accurate--perspective on the Python language. Ideally, a Python programmer will come away from this review with a few new insights on the familiar constructs she uses every day. This appendix does not shy away from using some abstract terms from computer science--if a particular term is not familiar to you, you will not lose much by skipping over the sentence it occurs in; some of these terms are explained briefly in the Glossary.
甚至对 python 很熟悉的读者可能都会喜欢这篇回顾。 这篇摘要的目标及 spin 和大部分介绍文章都不一样。 我相信我这种对语言特色分类和解释的方式能为你提供一种新鲜的——也是同样准确的——看待 python 语言的角度。 理想的情况下,python 程序员看完这篇回顾后,应该会让他对自己经常使用的熟知的东西(constructs)有一些新的看法。 这篇附录不会特意回避一些计算机科学里面的抽象术语——如果你对某一术语不熟悉,你大可直接跳过那一段,不会有什么损失的; 某些术语在术语表中有简短的解释。
python 属于哪种类型的语言
SECTION -- What Kind of Language is Python? --------------------------------------------------------------------
- Python is a byte-code compiled programming language that supports multiple programming paradigms. Python is sometimes called an interpreted and/or scripting language because no separate compilation step is required to run a Python program; in more precise terms, Python uses a virtual machine (much like Java or Smalltalk) to run machine-abstracted instructions. In most situations a byte-code compiled version of an application is cached to speed future runs, but wherever necessary compilation is performed "behind the scenes."
python 是一个字节码编译型的语言,它支持多种编程范式。 由于运行一个 python 程序并不需要单独的编译步骤,所以有时候 python 也被叫做是解释型的 和/或 脚本语言; 用更精确的术语来说,python 使用一个虚拟机 (很像 Java 或是 Smalltalk) 来运行抽象机器的指令 (machine-abstracted instructions)。 在大部分情况下,一个被编译成字节码的应用程序会被缓存起来,这样在以后运行的时候可以加快速度, 不过不管在什么地方进行的必要的编译过程都是在“幕后”悄悄完成的。
- In the broadest terms, Python is an imperative programming language, rather than a declarative (functional or logical) one. Python is dynamically and strongly typed, with very late binding compared to most languages. In addition, Python is an object-oriented language with strong introspective facilities, and one that generally relies on conventions rather than enforcement mechanisms to control access and visibility of names. Despite its object-oriented core, much of the syntax of Python is designed to allow a convenient procedural style that masks the underlying OOP mechanisms. Although Python allows basic functional programming (FP) techniques, side effects are the norm, evaluation is always strict, and no compiler optimization is performed for tail recursion (nor on almost any other construct).
用最宽泛的术语来说,python 是一种命令式 (imperative) 的编程语言,而非声明式 (函数式或逻辑式) 的。 python 是动态类型且是强类型的语言,相对大部分语言来说它拥有真正的迟绑定。 另外 python 还是一个拥有强大内省 (introspective) 机制的面向对象语言, 它依赖于约定而非强制机制来进行访问控制和名字的可见性控制。 撇开它的面向对象的核心,python 的大部分语法都设计成方便的面向过程式 (procedural) 的风格, 通过它来 (mask) 底层的面向对象机制。 虽然 python 允许基本的函数式编程 (FP) 技术,不过边界效应 (side effects) 还是正常的 (norm), 求值也总是严格的,而且还不会对尾递归(还有几乎所有其它的东西)进行编译器优化。
- Python has a small set of reserved words, delimits blocks and structure based on indentation only, has a fairly rich collection of built-in data structures, and is generally both terse and readable compared to other programming languages. Much of the strength of Python lies in its standard library and in a flexible system of importable modules and packages.
python 有一个不大的保留字集合,分界块 (delimits blocks) 和仅基于缩进的层次结构, 还拥有一组相当丰富的内置数据结构,而且相对其它语言来说很简洁,可读性也很强。 python 很多强大能力存在于它的标准库和灵活的模块/包系统之中。
名字空间与绑定
SECTION -- Namespaces and Bindings --------------------------------------------------------------------
- The central concept in Python programming is that of a namespace. Each context (i.e., scope) in a Python program has available to it a hierarchically organized collection of namespaces; each namespace contains a set of names, and each name is bound to an object. In older versions of Python, namespaces were arranged according to the "three-scope rule" (builtin/global/local), but Python version 2.1 and later add lexically nested scoping. In most cases you do not need to worry about this subtlety, and scoping works the way you would expect (the special cases that prompted the addition of lexical scoping are mostly ones with nested functions and/or classes).
使用 python 编程的核心概念就是名字空间。 python 程序中的每一个上下文 (或者说是作用范围) 都拥有一组层次结构的名字空间; 每一个名字空间包含一组名字,每一个名字绑定到一个对象。 在老版本的 python 中,使用 “三层范围规则” (内置/全局/局部) 对名字空间进行组织, 不过 python 2.1 及其后的版本都增加了嵌套的作用范围。 在大部分情况下你并不需要考虑这种微妙的东西,而且作用范围工作的方式和你所期待的是一样的。 (需要增加另外的 lexical scoping 的特例大部分都是嵌套函数 和/或 嵌套类)
- There are quite a few ways of binding a name to an object within the current namespace/scope and/or within some other scope. These various ways are listed below.
有好几种方法可以在当前的名字空间/作用范围 和/或 一些其它的作用范围中将一个名字绑定到对象上去。 这些方法有:
赋值和解除引用
- TOPIC -- Assignment and Dereferencing
--------------------------------------------------------------------
- A Python statement like 'x=37' or 'y="foo"' does a few things. If an object--e.g., '37' or '"foo"'--does not exist, Python creates one. If such an object -does- exist, Python locates it. Next, the name 'x' or 'y' is added to the current namespace, if it does not exist already, and that name is bound to the corresponding object. If a name already exists in the current namespace, it is re-bound. Multiple names, perhaps in multiple scopes/namespaces, can be bound to the same object.
像 'x=37' 或 'y="foo"' 这样的 python 表达式干了好几件事。 如果该对象—— 比如说 '37' 或是 '"foo"' ——不存在,python 就创建一个。 如果该对象存在,python 则定位到它。 然后,如果名字 'x' 或 'y' 不存在的话,就会被加到当前的名字空间中, 并且这个名字被绑定到相应的对象。如果当前名字空间中该名字已经存在,它就被重新绑定。 多个名字,可能还在多个作用范围/名字空间中,都可以绑定到同一个对象。
- A simple assignment statement binds a name into the current namespace, unless that name has been declared as global. A name declared as global is bound to the global (module-level) namespace instead. A qualified name used on the left of an assignment statement binds a name into a specified namespace--either to the attributes of an object, or to the namespace of a module/package, for example:
一个简单的赋值语句会将一个名字绑定到当前的名字空间中,除非该名字已经被声明成 global 了。 一个定义为 global 的名字被绑定到全局 (模块级) 名字空间中。 在赋值语句左边出现的受限名字 (qualified name) 将一个名字绑定到一个指定的名字空间——可能是对象的属性,或是模块/包的名字空间, 比如:
1 >>> x = "foo" # bind 'x' in global namespace
2 >>> def myfunc(): # bind 'myfunc' in global namespace
3 ... global x, y # specify namespace for 'x', 'y'
4 ... x = 1 # rebind global 'x' to 1 object
5 ... y = 2 # create global name 'y' and 2 object
6 ... z = 3 # create local name 'z' and 3 object
7 ...
8 >>> import package.module # bind name 'package.module'
9 >>> package.module.w = 4 # bind 'w' in namespace package.module
10 >>> from mymod import obj # bind object 'obj' to global namespace
11 >>> obj.attr = 5 # bind name 'attr' to object 'obj'
1 >>> x = "foo" # 将 'x' 绑定到全局名字空间
2 >>> def myfunc(): # 将 'myfunc' 绑定到全局名字空间
3 ... global x, y # 为 'x', 'y' 指定名字空间
4 ... x = 1 # 将全局名字 'x' 重绑定到对象 1
5 ... y = 2 # 创建全局名字 'y' 和对象 2
6 ... z = 3 # 创建局部名字 'z' 和对象 3
7 ...
8 >>> import package.module # 绑定名字 'package.module'
9 >>> package.module.w = 4 # 将 'w' 绑定到名字空间 package.module
10 >>> from mymod import obj # 将对象 'obj' 绑定到全局名字空间
11 >>> obj.attr = 5 # 将名字 'attr' 绑定到对象 'obj'
- Whenever a (possibly qualified) name occurs on the right side of an assignment, or on a line by itself, the name is dereferenced to the object itself. If a name has not been bound inside some accessible scope, it cannot be dereferenced; attempting to do so
raises a 'NameError' exception. If the name is followed by left and right parentheses (possibly with comma-separated expressions between them), the object is invoked/called after it is dereferenced. Exactly what happens upon invocation can be controlled and overridden for Python objects; but in general, invoking a function or method runs some code, and invoking a class creates an instance. For example:
无论何时一个名字(可能是受限的)出现在赋值语句的右边,或者在只有它自己的行中, 该名字都会被解除引用而得到它引用的对象。 如果一个名字没有被绑定到某个可访问的作用范围里面,它就不能被解除引用; 如果试图这样做的话会抛出一个 'NameError' 的异常。如果名字后面跟着左右两个括号 (其中可能还有逗号分割的表达式), 在解除引用后,该对象会被调用。调用期间实际干些什么事情可以被 python 对象控制和重写。 不过通常调用一个函数或方法会执行一些代码,调用一个 class 会创建一个实例。 比如:
函数和类的定义
- TOPIC -- Function and Class Definitions
--------------------------------------------------------------------
- Declaring a function or a class is simply the preferred way of describing an object and binding it to a name. But the 'def' and 'class' declarations are "deep down" just types of assignments.
In the case of functions, the lambda operator can also be used on the right of an assignment to bind an "anonymous" function to a name. There is no equally direct technique for classes, but their declaration is still similar in effect:
定义一个函数或类简直是描述一个对象并将它绑定到一个名字的首选方式了。 不过 'def' 和 'class' 声明本质上 (deep down) 只是赋值的不同形式罢了。 拿函数来说,我们还可以在赋值语句的右边使用'lambda' 运算符,这样可以绑定一个“匿名”函数到一个名字。 对于类来说没有和它等价的便捷技术,不过在效果上它们的声明还是很相似的:
'import' 表达式
- TOPIC -- 'import' Statements
--------------------------------------------------------------------
- Importing, or importing -from-, a module or a package adds or modifies bindings in the current namespace. The 'import' statement has two forms, each with a bit different effect. Statements of the forms:
导入——或者从某处导——一个模块或者一个包,会在当前名字空间中添加或修改一些绑定。 'import' 表达式有两种形式,每一种都有稍微不同的效果。
这种形式的表达式:
- add a new module object to the current namespace. These module objects themselves define namespaces that you can bind values in or utilize objects within.
在当前名字空间中增加一个新的模块对象。 这些模块对象本身定义了名字空间,你可以绑定值到其中,也可以利用其中的对象。
- Statements of the forms:
这种形式的表达式:
- ..instead add the names 'foo' or 'bar' to the current namespace. In any of these forms of 'import', any statements in the imported module are executed--the difference between the forms is simply the effect upon namespaces.
则向当前名字空间添加名字 'foo' 或 'bar'。 'import' 表达式的任何一个形式中,被导入的模块中的所有表达式都会被执行——区别只在于对名字空间产生的效果。
- There is one more special form of the 'import' statement; for example:
这是 'import' 表达式的一种更特殊的形式:
1 >>> from modname import *
- The asterisk in this form is not a generalized glob or regular expression pattern, it is a special syntactic form. "Import star" imports every name in a module namespace into the current namespace (except those named with a leading underscore, which can still be explicitly imported if needed). Use of this form is somewhat discouraged because it risks adding names to the current namespace that you do not explicitly request and that may rebind existing names.
这种形式中的星号不是一个通用形式的 glob 也不是正则表达式的模式,它是一个特殊的语法形式。 "Import star" 会将模块名字空间中的所有名字导入到当前名字空间中来 (除了那些以下划线开头的名字,如果需要的话它们也可以被显示地导入进来)。 我们不太提倡这种形式的 import ,因为它可能会添加一些你明显并不需要的名字到当前名字空间, 还可能重绑定已有名字。
'for' 表达式
- TOPIC -- 'for' Statements
--------------------------------------------------------------------
- Although 'for' is a looping construct, the way it works is by binding successive elements of an iterable object to a name (in the current namespace). The following constructs are (almost) equivalent:
虽然 'for' 是用来建立循环的,不过它工作的方式是通过将一个可迭代 (iterable) 对象中的连续元素绑定到一个名字 (在当前名字空间中)
来完成的。以下语句是 (几乎) 等价的:
'except' 表达式
- TOPIC -- 'except' Statements
--------------------------------------------------------------------
- The 'except' statement can optionally bind a name to an exception argument:
'except' 表达式可选地将一个名字绑定到一个异常参数上:
数据类型
SECTION -- Datatypes
--------------------------------------------------------------------
- Python has a rich collection of basic datatypes. All of Python's collection types allow you to hold heterogeneous elements inside them, including other collection types (with minor limitations). It is straightforward, therefore, to build complex data structures in Python.
python 有一组丰富的基本数据类型。所有 python 的 collection 类型 都可以在其中包含不同类型的元素,甚至其它 collection 类型 (会稍微有点限制)。 因此,在 python 中构建复杂数据结构变得非常简单。
- Unlike many languages, Python datatypes come in two varieties: mutable and immutable. All of the atomic datatypes are immutable, as is the collection type 'tuple'. The collections 'list' and 'dict' are mutable, as are class instances. The mutability of a datatype is simply a question of whether objects of that type can be changed "in place"--an immutable object can only be created and destroyed, but never altered during its existence. One upshot of this distinction is that immutable objects may act as dictionary keys, but mutable objects may not. Another upshot is that when you want a data structure--especially a large one--that will be modified frequently during program operation, you should choose a mutable datatype (usually a list).
和许多其他语言都不一样,python 的数据类型分为两种:可变的和不可变的。 所有原子数据类型都是不可变的数据类型,包括 collection 类型 'tuple' 也是属于这类的。 collection 数据类型 'list' 和 'dict' 是可变的,包括类、实例都是属于这一类的。 一个数据类型的可变性说的其实就是该类型的对象是否可以“就地”修改—— 不可变的对象就只能够对它们进行创建和销毁,不可能在它们存在的期间对它们进行修改。 这种区分导致的一个结果就是不可变对象可以作为字典的 key,而可变对象不能。 导致的另一个结果就是如果需要一个数据结构——特别是很大的数据结构—— 要在程序操作期间经常被修改,那你应该选择一个可变的数据结构(通常是一个 list)。
- Most of the time, if you want to convert values between different Python datatypes, an explicit conversion/encoding call is required, but numeric types contain promotion rules to allow numeric expressions over a mixture of types. The built-in datatypes are listed below with discussions of each. The built-in
function type() can be used to check the datatype of an object.
大部分时候,如果你想在不同 python 数据类型之间对值进行转换,需要显示地进行转换(或者说编码)调用,不过数值类型包含有 提升 (promotion) 规则,可以允许数值表达式中混合多种类型。下面列出所有内置数据类型和相关的讨论。 内置函数 type() 可以用来查看一个对象的类型。
简单类型
- TOPIC -- Simple Types
--------------------------------------------------------------------
- Python 2.3+ supports a Boolean datatype with the possible values 'True' and 'False'. In earlier versions of Python, these values are typically called '1' and '0'; even in Python 2.3+, the Boolean values behave like numbers in numeric contexts. Some earlier micro-releases of Python (e.g., 2.2.1) include the -names- 'True' and 'False', but not the Boolean datatype.
python 2.3 及其后续版本支持 Boolean 数据类型,只能取 'True' 和 'False' 两个值。 在 python 更早期的版本中,这些值被象征性地叫做 '1' 和 '0';甚至在 python2.3 及其后续版本中,Boolean 型值在数值环境中的行为也很像数字。有一些更早的 python micro-releases (比如 2.2.1) 中包含有名字 'True' 和 'False',不过不是 Boolean 数据类型
- int
- A signed integer in the range indicated by the register size of the interpreter's CPU/OS platform. For most current platforms, integers range from (2**31)-1 to negative (2**31)-1. You can find the size on your platform by
examining sys.maxint. Integers are the bottom numeric type in terms of promotions; nothing gets promoted -to- an integer, but integers are sometimes promoted to other numeric types. A float, long, or string may be explicitly converted to an int using the int() function. SEE ALSO, [int]
- A signed integer in the range indicated by the register size of the interpreter's CPU/OS platform. For most current platforms, integers range from (2**31)-1 to negative (2**31)-1. You can find the size on your platform by
有符号整数的范围由解释器所处的 CPU/OS 平台的寄存器大小决定。 对目前大部分平台来说,整数的范围是从负 (2**31)-1 到正 (2**31)-1 。 你可以通过 sys.maxint 查看在你的平台上的大小。 按照提升 (promotion) 规则来说整数是最基础的数值类型; 没有东西可以被提升 (promotion) 为一个整数,但是整数有时候会被提升为其他数值类型。 浮点数、长整型,或者字符串都可以通过 int() 函数显式地转换成整数。
- long
- An (almost) unlimited size integral number. A long literal is indicated by an integer followed by an 'l' or 'L' (e.g., '34L', '9876543210l'). In Python 2.2+, operations on ints
that overflow sys.maxint are automatically promoted to longs. An int, float, or string may be explicitly converted to a long using the long() function.
- An (almost) unlimited size integral number. A long literal is indicated by an integer followed by an 'l' or 'L' (e.g., '34L', '9876543210l'). In Python 2.2+, operations on ints
这是个 (几乎) 没有大小限制的整数。 后面跟着一个 'l' 或 'L' 的整数表示一个长整数(比如 '34L', '9876543210l')。 python 2.2 及其后续版本中,在超过 sys.maxint 的整数上进行操作会自动提升为长整数。 整数、浮点数或字符串可以通过 long() 函数显式地转换为长整数。
- float
- An IEEE754 floating point number. A literal floating point number is distinguished from an int or long by containing a decimal point and/or exponent notation (e.g., '1.0', '1e3', '.453e-12', '37.'). A numeric expression that involves both int/long types and float types promotes all component types to floats before performing the computation. An int, long, or string may be explicitly converted to a float using the
float() function. SEE ALSO, [float]
- An IEEE754 floating point number. A literal floating point number is distinguished from an int or long by containing a decimal point and/or exponent notation (e.g., '1.0', '1e3', '.453e-12', '37.'). A numeric expression that involves both int/long types and float types promotes all component types to floats before performing the computation. An int, long, or string may be explicitly converted to a float using the
这是 IEEE754 浮点数。浮点数于整数或长整数在字面上的区别在于包含了十进制的小数部分 和/或 指数符号(比如 '1.0', '1e3', '.453e-12', '37.')。一个同时涉及到 整数/长整数 和浮点数的数值表达式会将所有类型提升为浮点型,然后才进行计算。 整数、长整数或字符串都可以通过 float() 函数显式转换为浮点数。
- complex
- An object containing two floats, representing real and imaginary components of a number. A numeric expression that involves both int/long/float types and complex types promotes all component types to complex before performing the computation. There is no way to spell a literal complex in Python, but an addition such as '1.1+2j' is the usual way of computing a complex value. A 'j' or 'J' following a float or int literal indicates an imaginary number. An int, long, or string may be explicitly
converted to a complex using the complex() function. If two float/int arguments are passed to complex(), the second is the imaginary component of the constructed number (e.g., 'complex(1.1,2)').
- An object containing two floats, representing real and imaginary components of a number. A numeric expression that involves both int/long/float types and complex types promotes all component types to complex before performing the computation. There is no way to spell a literal complex in Python, but an addition such as '1.1+2j' is the usual way of computing a complex value. A 'j' or 'J' following a float or int literal indicates an imaginary number. An int, long, or string may be explicitly
这是个包含两个浮点数的对象,分别表示数字中的实部和虚部。 同时涉及到 整数/长整数/浮点数 和复数的数值表达式会将所有类型都提升为复数然后才进行计算。 在 python 中没有用来表达复数的字面量 (literal), 不过像 '1.1+2j' 这样的加法常常用来计算一个复数。 在一个浮点数后面跟一个 'j' 或 'J' 表示一个虚数。 整数、长整数或字符串都可以通过 complex() 函数显式转换地为复数。 如果给 complex() 传递两个浮点型/整型参数,那么第二个将成为虚数部分。
- string
- An immutable sequence of 8-bit character values. Unlike in many programming languages, there is no "character" type in Python, merely strings that happen to have length one. String objects have a variety of methods to modify strings, but such methods always return a new string object rather than modify the initial object itself. The built-in
chr() function will return a length-one string whose ordinal value is the passed integer. The str() function will return a string representation of a passed in object. For example:
- An immutable sequence of 8-bit character values. Unlike in many programming languages, there is no "character" type in Python, merely strings that happen to have length one. String objects have a variety of methods to modify strings, but such methods always return a new string object rather than modify the initial object itself. The built-in
一个不可变的8位字符的序列。 不像许多其他编程语言,python 中没有字符型,只有长度为1的字符串。 字符串对象有许多方法可以用来修改字符串, 不过这些方法总是返回一个新的字符串对象, 而不是修改一开始那个。 内置函数 chr() 会返回一个长度为1的字符串,它的 ascil 码值为传入的整数。 str() 函数返回传入对象的字符串表现形式。比如:
- SEE ALSO, [string]
- unicode
- An immutable sequence of Unicode characters. There is no datatype for a single Unicode character, but unicode strings of length-one contain a single character. Unicode strings contain a similar collection of methods to string objects, and like the latter, unicode methods return new unicode objects rather than modify the initial object. See Chapter 2 and Appendix C for additional discussion, of Unicode.
一个不可变的 Unicode 字符序列。 没有表达单个 Unicode 字符的数据类型,不过长度为1的 unicode 字符串包含单个字符。 Unicode 字符串包含一组和字符串对象类似的方法,而且和后者一样, unicode的方法也是返回新的 unicode 对象,而非修改一开始那个。 第2章和 附录 C 中有更多 Unicode 的讨论。