The Python Tutorial 9. Classes

来源:互联网 发布:外国直播软件 编辑:程序博客网 时间:2024/05/16 18:06

The <wbr>Python <wbr>Tutorial <wbr>9. <wbr>Classes

时间不够直接跳过前边一些东西,从9.3开始

 

9.3. A First Look at Classes

Classes introducea little bit of new syntax, three new object types, and some newsemantics.

  9.3.1. Class Definition Syntax

类语法,下面是一个很简单的class的定义。

The simplest formof class definition looks like this:

class ClassName:    <statement-1>    .    .    .    <statement-N>

Classdefinitions, like function definitions (def statements)must be executed before they have any effect. (You couldconceivably place a class definition in a branch ofan if statement,or inside a function.)

In practice, thestatements inside a class definition will usually be functiondefinitions, but other statements are allowed, and sometimes useful— we’ll come back to this later. The function definitions inside aclass normally have a peculiar form of argument list, dictated bythe calling conventions for methods — again, this is explainedlater.

When a classdefinition is entered, a new namespace is created, and used as thelocal scope — thus, all assignments to local variables go into thisnew namespace. In particular, function definitions bind the name ofthe new function here.

When a classdefinition is left normally (via the end),a classobject is created. This isbasically a wrapper around the contents of the namespace created bythe class definition; we’ll learn more about class objects in thenext section. The original local scope (the one in effect justbefore the class definition was entered) is reinstated, and theclass object is bound here to the class name given in the classdefinition header (ClassName inthe example).

 

9.3.2. Class Objects

类对象,支持两种操作,attribute references 和instantiation

Class objectssupport two kinds of operations: attribute references andinstantiation.

Attributereferences use the standard syntax usedfor all attribute references inPython: obj.name.Valid attribute names are all the names that were in the class’snamespace when the class object was created. So, if the classdefinition looked like this:

attributereferences 是标准的语法,可以这样引用:obj.name

class MyClass:    """A simple example class"""    i = 12345    def f(self):        return 'hello world'

then MyClass.i and MyClass.f arevalid attribute references, returning an integer and a functionobject, respectively. Class attributes can also be assigned to, soyou can change the valueof MyClass.i byassignment. __doc__ isalso a valid attribute, returning the docstring belonging to theclass: "A simple example class".

Class instantiation usesfunction notation. Just pretend that the class object is aparameterless function that returns a new instance of the class.For example (assuming the above class):

第二种方法instantiation要用function来标记才行。调用函数以后会返回一个实例。可以像下面一样调用了

x = MyClass()

 

creates anew instance ofthe class and assigns this object to the localvariable x.

The instantiationoperation (“calling” a class object) creates an empty object. Manyclasses like to create objects with instances customized to aspecific initial state. Therefore a class may define a specialmethod named__init__(),like this:

def __init__(self):    self.data = []

When a classdefines an __init__() method,class instantiation automaticallyinvokes __init__() forthe newly-created class instance. So in this example, a new,initialized instance can be obtained by:

x = MyClass()

Of course,the __init__() methodmay have arguments for greater flexibility. In that case, argumentsgiven to the class instantiation operator are passed onto __init__().For example,

>>> class Complex:...     def __init__(self, realpart, imagpart):...         self.r = realpart...         self.i = imagpart...>>> x = Complex(3.0, -4.5)>>> x.r, x.i(3.0, -4.5)

9.5. Inheritance

Of course, a language feature would not be worthy of the name“class” without supporting inheritance. The syntax for a derivedclass definition looks like this:

一个没有继承的class就不能称为class

class DerivedClassName(BaseClassName):    <statement-1>    .    .    .    <statement-N>

The name BaseClassName mustbe defined in a scope containing the derived class definition. Inplace of a base class name, other arbitrary expressions are alsoallowed. This can be useful, for example, when the base class isdefined in another module:

基类的名字就在上面的例子中定义,代替掉基类的名称,其他表达式也是被允许的。下面看看例子

class DerivedClassName(modname.BaseClassName):

Execution of a derived class definition proceeds the same as for abase class. When the class object is constructed, the base class isremembered. This is used for resolving attribute references: if arequested attribute is not found in the class, the search proceedsto look in the base class. This rule is applied recursively if thebase class itself is derived from some other class.

There’s nothing special about instantiation of derivedclasses: DerivedClassName() createsa new instance of the class. Method references are resolved asfollows: the corresponding class attribute is searched, descendingdown the chain of base classes if necessary, and the methodreference is valid if this yields a function object.

Derived classes may override methods of their base classes. Becausemethods have no special privileges when calling other methods ofthe same object, a method of a base class that calls another methoddefined in the same base class may end up calling a method of aderived class that overrides it. (For C++ programmers: all methodsin Python are effectively virtual.)

An overriding method in a derived class may in fact want to extendrather than simply replace the base class method of the same name.There is a simple way to call the base class method directly: justcall BaseClassName.methodname(self,arguments).This is occasionally useful to clients as well. (Note that thisonly works if the base class is accessible as BaseClassName inthe global scope.)

Python has two built-in functions that work with inheritance:

  • Use isinstance() tocheck an instance’stype: isinstance(obj, int) willbe True onlyif obj.__class__ is int orsome class derivedfrom int.
  • Use issubclass() tocheck classinheritance: issubclass(bool, int) is True since bool isa subclass of int.However,issubclass(unicode, str) is False since unicode isnot a subclass of str (theyonly share a common ancestor,basestring).

 

9.6. Private Variables

private这个实例变量不能随便被修改,除非不纯在一个对象里边。通常用带下划线前缀名称标识非公共API的部分。

“Private”instance variables that cannot be accessed except from inside anobject don’t exist in Python. However, there is a convention thatis followed by most Python code: a name prefixed with an underscore(e.g. _spam)should be treated as a non-public part of the API (whether it is afunction, a method or a data member). It should be considered animplementation detail and subject to change without notice.

Since there is avalid use-case for class-private members (namely to avoid nameclashes of names with names defined by subclasses), there islimited support for such a mechanism, called namemangling. Any identifier of the form__spam (atleast two leading underscores, at most one trailing underscore) istextually replacedwith _classname__spam,where classname isthe current class name with leading underscore(s) stripped. Thismangling is done without regard to the syntactic position of theidentifier, as long as it occurs within the definition of aclass.

Name mangling ishelpful for letting subclasses override methods without breakingintraclass method calls. For example:

class Mapping:    def __init__(self, iterable):        self.items_list = []        self.__update(iterable)    def update(self, iterable):        for item in iterable:            self.items_list.append(item)    __update = update   # private copy of original update() methodclass MappingSubclass(Mapping):    def update(self, keys, values):        # provides new signature for update()        # but does not break __init__()        for item in zip(keys, values):            self.items_list.append(item)

Note that themangling rules are designed mostly to avoid accidents; it still ispossible to access or modify a variable that is considered private.This can even be useful in special circumstances, such as in thedebugger.

Notice that codepassed to exec, eval_r() or execfile() doesnot consider the classname of the invoking class to be the currentclass; this is similar to the effect ofthe global statement,the effect of which is likewise restricted to code that isbyte-compiled together. The same restriction appliesto getattr(), setattr() and delattr(),as well as when referencing __dict__ directly.

 

原创粉丝点击