无聊之人--除了技术,还是技术,你懂得
分类: Python/Ruby
2011-07-01 23:41:15
5.3. Defining Classes
5.3 定义类
Python is fully object-oriented: you can define your own classes, inherit from your own or built-in classes, and instantiate the classes you've defined.
Python是完全面向对象的。你可以定义你自己的类,继承你自己或是内置的类,然后实例化你自己的定义的类。
Defining a class in Python is simple. As with functions, there is no separate interface definition. Just define the class and start coding. A Python class starts with the reserved word class, followed by the class name. Technically, that's all that's required, since a class doesn't need to inherit from any other class.
在Python中定义一个类是十分简单的。如同函数一样不存在单独到接口定义。仅仅定义了和开始代码。在Python中,一个类以保留字class开始,后面紧跟着类的名字。从技术的角度将,这是全部必须的,这是因为一个类不必继承任何类。
Example 5.3. The Simplest Python Class
例5.3 最简单的Python类
The name of this class is Loaf, and it doesn't inherit from any other class. Class names are usually capitalized, EachWordLikeThis, but this is only a convention, not a requirement. 类的名字是Loaf,而且它没有继承自任何类。类的名字通常是首字母大写的,每个字母首字母大写(EachWordLikeThis),但是这仅仅是一种传统,而不是必须的。 |
|
|
||
This class doesn't define any methods or attributes, but syntactically, there needs to be something in the definition, so you use pass. This is a Python reserved word that just means “move along, nothing to see here”. It's a statement that does nothing, and it's a good placeholder when you're stubbing out functions or classes. 这个类没有定义任何属性和方法,但是从语义的角度考虑,需要在类中定义一些东西,因此你是使用pass。这同样是Python中的一个保留字,它的意思是“继续往前,这儿什么也看不到”。它就是一个语句,什么也不做。但是当你打算清除函数或是类的时候,它是一个很好的占位符。 |
|
|
||
You probably guessed this, but everything in a class is indented, just like the code within a function, if statement, for loop, and so forth. The first thing not indented is not in the class. 你可能在这个会猜是不是有某写东西,但是类中的所有东西都是缩进的,同函数,if语句,for循环等等中的代码缩进是相同的。类中没有缩进的代码不属于该类。 |
|
|
||
|
|
|
||
|
The pass statement in Python is like an empty set of braces ({}) in Java or C. Python中的pass语句同java或是C中的空语句{}是类似的。 |
|
||
|
Of course, realistically, most classes will be inherited from other classes, and they will define their own class methods and attributes. But as you've just seen, there is nothing that a class absolutely must have, other than a name. In particular, C++ programmers may find it odd that Python classes don't have explicit constructors and destructors.Python classes do have something similar to a constructor: the __init__ method.
当然现实中,大多数的类都是从其它的类继承,同时这些类也会定义它们自己的类方法和属性。但是正如你所看到的,在类中可以什么都不包含但是必须有一个名字。特别是对C++程序员而言,他会发现Python类中没有显式的构造函数和析构函数很是奇怪。Python函数包含函数__init__ 方法,它的作用同构造函数类似。
Example 5.4. Defining the FileInfo Class
例5.4 定义FileInfo 类
In Python, the ancestor of a class is simply listed in parentheses immediately after the class name. So the FileInfo class is inherited from the UserDict class (which wasimported from the UserDict module). UserDict is a class that acts like a dictionary, allowing you to essentially subclass the dictionary datatype and add your own behavior. (There are similar classes UserList and UserString which allow you to subclass lists and strings.) There is a bit of black magic behind this, which you will demystify later in this chapter when you explore the UserDict class in more depth. 在Python中,一个类的祖先就是简单的罗列在紧跟着类名字的括号中。因此类FileInfo继承自类UserDict类(该类从模块UserDict中导入)。UserDict类的作用就像一个字典,它允许你子类化字典数据类型并增加你自己的行为。(类似的类UserList和UserString,它们允许你子类化列表和字符串)。在这背后有一些魔术技巧,稍后在你深层探讨UserDict类时来阐述它。 |
|
|
||
|
|
|
||
|
In Python, the ancestor of a class is simply listed in parentheses immediately after the class name. There is no special keyword like extends in Java. 在Python中,一个类的祖先就是简单的罗列在紧跟着类名字的括号中。这儿没有关键字如java中的extend。 |
|
||
|
Python supports multiple inheritance. In the parentheses following the class name, you can list as many ancestor classes as you like, separated by commas.
Python支持多重继承。在紧跟类名字的括号中,你可以罗列尽可能多的祖先类,祖先类之间通过逗号来分隔。
5.3.1. Initializing and Coding Classes
5.31 初始化和 coding类
This example shows the initialization of the FileInfo class using the __init__ method.
下面这个例子说明了使用__init__来初始化类FileInfo类。
Example 5.5. Initializing the FileInfo Class
例5.5 初始化类FileInfo
Classes can (and should) have doc strings too, just like modules and functions. 同函数和模块一样,类同样也应该拥有自己的doc string。 |
|
|
||
__init__ is called immediately after an instance of the class is created. It would be tempting but incorrect to call this the constructor of the class. It's tempting, because it looks like a constructor (by convention, __init__ is the first method defined for the class), acts like one (it's the first piece of code executed in a newly created instance of the class), and even sounds like one (“init” certainly suggests a constructor-ish nature). Incorrect, because the object has already been constructed by the time __init__ is called, and you already have a valid reference to the new instance of the class. But __init__ is the closest thing you're going to get to a constructor in Python, and it fills much the same role. __init__方法在类实例被创建后直接调用。它应该尝试但是确实不正确的调用该类的构造函数。说它尝试,是因为它看起来像是一个构造函数(根据传统,__init__方法是类中定义的第一个函数,它表现如同一个构造函数(它是类实例新创建后第一段被执行的代码),而且听起来也像一个构造函数(“init”从某种意义上暗示了它具有一个构造函数的特性)。不正确,是因为在调用__init__函数以前,对象已经被构建出来,已经拥有了一个对类实例对象的合法的引用的。但是__init__是你在Python中能访问构造函数的最方便的方法,很大程度上它们充当了同样的角色。 |
|
|
||
The first argument of every class method, including __init__, is always a reference to the current instance of the class. By convention, this argument is always namedself. In the __init__ method, self refers to the newly created object; in other class methods, it refers to the instance whose method was called. Although you need to specify self explicitly when defining the method, you do not specify it when calling the method; Python will add it for you automatically. 每一个类方法的一个参数,包括__init__,通常是一个对当前类实例的引用。根据惯例,,参数的名字通常是self。在__init__方法中,self引用刚刚创建的对象;在其它方法中,it引用调用方法的对象。在定义一个方法时,你通常需要你需要显式的定义self,在调用方法是你不要说明:python会自动的替你添加。 |
|
|
||
__init__ methods can take any number of arguments, and just like functions, the arguments can be defined with default values, making them optional to the caller. In this case, filename has a default value of None, which is the Python null value. 同函数一样,__init__方法可以接受任意数目的参数,参数可以定义默认值,当调用者调用时它们是可选的。在本例中,filename有默认值None,也就是Python中的空值。 |
|
|
||
|
|
|
||
|
By convention, the first argument of any Python class method (the reference to the current instance) is called self. This argument fills the role of the reserved word this in C++ or Java, but self is not a reserved word in Python, merely a naming convention. Nonetheless, please don't call it anything but self; this is a very strong convention. 依据惯例,任意Python类函数的第一个参数(对当前实例的引用)被称为self。这个参数的角色同C++或是java中的self一样,但是self不是Python中的保留字,仅是一个命名惯例。尽管如此,不要把它命名为除self以外的任何其它对象:这是一个非常重要的传统。 |
|
||
|
Example 5.6. Coding the FileInfo Class
例5.6 coding FileInfo类
Some pseudo-object-oriented languages like Powerbuilder have a concept of “extending” constructors and other events, where the ancestor's method is called automatically before the descendant's method is executed. Python does not do this; you must always explicitly call the appropriate method in the ancestor class. 一些伪面向对象语言如Powerbuilder,含有一个概念“扩展“构造函数以及其它事件,也就是在后代方法子在执行之前祖先类的方法被自动调用。Python不这样做。你必须显式的调用祖先类中的方法。 |
|
I told you that this class acts like a dictionary, and here is the first sign of it. You're assigning the argument filename as the value of this object's name key. 这个类表现的同字典一样,这是第一个标识。你在对filename进行赋值,作为对象name键的值。 |
|
Note that the __init__ method never returns a value. 注意__init__方法绝不会有返回值 |
5.3.2. Knowing When to Use self and __init__
5.3.2 知道何时使用self和__init__
When defining your class methods, you must explicitly list self as the first argument for each method, including __init__. When you call a method of an ancestor class from within your class, you must include the self argument. But when you call your class method from outside, you do not specify anything for the self argument; you skip it entirely, and Python automatically adds the instance reference for you. I am aware that this is confusing at first; it's not really inconsistent, but it may appear inconsistent because it relies on a distinction (between bound and unbound methods) that you don't know about yet.
当你定义一个类方法时,你必须显式的将self作为每一个方法的第一个参数,包括 __init__。当你从自己的类中调用一个祖先类的方法时,你必须包含self函数。但是你从外边调用你自己的类方法时,你不必限定self参数;你可以完全忽略它,Python会自动的给提增加上对调用对象的引用。我发现刚开始的很容易混淆;它实际上并不一致,它表现的也并不一致,因为它依赖于这种区别:绑定方法和未绑定方法的区别(现在还没有介绍)。
Whew. I realize that's a lot to absorb, but you'll get the hang of it. All Python classes work the same way, so once you learn one, you've learned them all. If you forget everything else, remember this one thing, because I promise it will trip you up:
我感觉到你需要吸收很多知识,但是你很快就回领会。所有的Python类都以相同的方式工作,因此一旦你学会了一个,你将学会全部。如果你忘记了所有的东西,请记住一件事,因为我可以保证的说它会然你的路途畅通无阻:
|
|
|
__init__ methods are optional, but when you define one, you must remember to explicitly call the ancestor's __init__ method (if it defines one). This is more generally true: whenever a descendant wants to extend the behavior of the ancestor, the descendant method must explicitly call the ancestor method at the proper time, with the proper arguments. __init__方法是可选的,但是定义一个的时候,你必须记住显式的调用祖先类的__init__方法(如果祖先类定义了一个__init__).同样正确的是:每当一个后代类想扩展祖先类的行为时,后代类方法必须在合适的实际,以合适的参数,显式的调用祖先类方法。 |
|