Python Guide - Class

zhaozj2021-02-11  221

Translator: The text section of this Python guide is complete, thanks to Clover sister, SICKKID, Yin Weiming, face, 珂 and other friends give me help and support from the translation process. Special thanks to Python Guide 2.2 (

Http://python.cn/contents/python_tutorial/python-tutorial.html of Li Dongfeng. In the last chapter, the terminology and other content have been revised and unified with reference to his translation, which greatly improves the work efficiency and the quality of this chapter.

Chapter directory

9.1 Topics of the terminology 9.2 Python action domain and namespace 9.3 initiating class

9.3.1 Class Definition Syntax 9.3.2 Class Objects 9.3.3 Instance Objects 9.3.4 Method Objects 9.4 Some Description 9.5 Inheritance

9.5.1 Multiple Inheritance 9.6 Private Variables 9.7 Supplement 9.8 Anomaly is also a class 9.9 iterator 9.10 generator

9. Class

Python joins the class mechanism as much as possible without adding new syntax and semantics. This mechanism is a mix of C and Python's Modula-3. The classes in Python do not create an absolute barrier between users and definitions, but depending on the user's consciousness, not "destroy definition". However, the most important function of the class mechanism is completely reserved. The class inheritance mechanism allows multiple inheritance, derived classes to override any method in the override base class, and the method of the same name in the base class can be invoked. Objects can contain any number of private members.

In terms of C terms, all class members (including data members) are public, and all member functions are virtual (Virtual). In terms of modula-3, there is nothing in a simple manner in a member method (shorthands) can refer the member of the object: The method function needs to be first parameters as the reference object when defined, and it will hidden when calling Citing object. This forms a semantic introduction and rename. (This Provides Semantics for Importing and Renaming.) However, like C instead of MODULA-3, most of the built-in operators (algorithm operators, subscripts, etc.) with special syntax can be redefined for classes.

9.1 Topics of the terminology

Since there is nothing about the generic term, I borrow some from SmallTalk and C (I want to use MODULA-3 because it is more close to Python than C , but I don't think how many readers have heard it) .

I want to remind the reader, there is an object-oriented term trap, and the word "object" in Python does not necessarily spectrum instance. Not all types in Python are class: For example, the built-in data type is not, or even some external types such as files are not, this is similar to C and Modula-3, not like SmallTalk. However, all Python types have a bit of semantics: describing their most appropriate words are "objects".

Objects are special, multiple names (in multiple scopes) can bind the same object. This is equivalent to alias in other languages. This is usually ignored in the first impression of Python, and it can also be very safe when using those non-variable basic types (values, strings, tuples). However, this semantics will have an impact when the Python code calls the dictionary, the variable object, and most of the types involving the program external entity (files, forms, etc.). This generic helps optimize the program because the alias behavior is similar to the pointer. For example, it is easy to pass an object because it only passes a pointer in behavior. If the function modifies an object passed through the parameter, the caller can receive changes - this requires two different parameter transfer mechanisms in Pascal. 9.2 Python scope and namespace

Before introducing the class, I first introduce some rules about the Python scope: the definition of the class is very cleverly uses the namespace. It is necessary to fully understand the knowledge, and need to understand the working principle of the scope and namespace. In addition, all knowledge is very useful for any advanced Python programmers.

We started from some definitions.

Namespace is a mapping named object. The current namespace is mainly implemented through the Python dictionary, but it is usually not concerned with specific implementation (unless it is considered), it may also change its implementation. There are some examples of namespaces: built-in naming (like ABS () ", and built-in exception names) set, local naming in the module in the module. Name. A genre set of objects in a sense is also a namespace. One important thing about namespace needs to be understood is that there is no contact in different namespaces, such as two different modules may define a function called "maximize" without confusion - users must The module is called to reference them.

By the way, I am called any "." After Python is named attribute - for example, REAL in the expression z.Real is an attribute of object Z. Strictly speaking, the reference naming from the module is a reference property: In the expression modname.funcname, MODNAME is a module object, and FuncName is an attribute. Therefore, the properties of the module and the global naming in the module have direct mapping relationships: they share the same namespace! 9.1

The attribute can be read or written. In the latter case, the attribute can be assigned. You can do this: "MODNAME.THE_ANSWER = 42". The writable properties can also be deleted with the DEL statement. For example: "DEL MODNAME.THE_ANSWER" will delete the_answer attribute from the MODNAME object.

Different namespaces are created at different times, there are different survival. The namespace containing the built-in named name is created when the Python interpreter is started, and will remain, not deleted. The global namespace of the module is created when the module definition is read, usually, the module namespace will always be saved to the interpreter exit. The statement that is executed by the interpreter at the highest layer, whether it is part of the __main__ module, whether it is from the script file or from an interactive input, so they also have their own namespace. (Built-in naming is also included in a module, it is called __builtin__.)

When a function is called, a partial namespace is created, and the function returns to throw an exception that does not process within the function. (In fact, it is more appropriate for forgetting. Of course, each recursive call has its own namespace.

The scope refers to the namespace that the Python program can access directly. "Direct Access" here means that additional modifiers do not need to be added when naming in the namespace. Although the scope is static definition, they are dynamic during use. At least three namespaces can be accessed directly, and the domain containing local named domain is in the most inside, first searched; secondly sector, the mid-layer scope, here contains the same level Function; Finally Search the outermost scope, it contains a built-in naming.

If a naming declaration is globally, all assignments and references are directly directed to the intermediate scope of the global named. In addition, variables of all inner layer scavenging domains accessed from the outside are read-only.

From the text sense, the local scope references the current function name. In addition to the function, the local scope is referenced to the same namespace with the global use domain: module namespace. Class definitions are also another namespace in the local scope.

The scope is determined in the source program: a global scope defined in a module is the namespace of the module, not the alias of the function being defined or called, understanding this is very important. On the other hand, the named actual search process is dynamic. It is determined at runtime - however, the Python language is constantly evolving. It may be determined when it is static "Compilation", so don't depend on dynamic analysis! (In fact, local variables are already static.)

One of Python is that its assignment operation is always in the proderation of the mileage. Assignment does not copy data - just binds naming to the object. This is also the same: "DEL X" is just deleting a namex from the namespace of the local scope. In fact, all the newly named operations act on the local scope. In particular, the IMPORT statement and the function set will bind the module name or function to the local scope. (You can use the Global statement to introduce variables to global scope.)

9.3 first knowledge class

The class introduces a new syntax, three new object types, and some new semantics.

9.3.1 Class definition syntax

The simplest type definition form is as follows:

Class classname:

.

.

.

The definition of the class is like a function definition (DEF statement), and it is necessary to take effect first. (You can of course put it in a branch of the IF statement, or the inside of a function.)

It is usually the definition of the class definition statement is usually the function definition, but other statements can be, sometimes it is useful - later we will return to discuss. The function definition in the class typically includes a special form of parameter list for method calls, and we discuss this later.

When defining a class, create a new namespace, use it as a local scope - therefore, so the assignment of local variables is introduced into a new namespace. In particular, the function definition is bound to this.

When the class definition is complete (normal exit), a class object is created. Basically, it is a packaging for the namespace created by class definitions; we learn more about the knowledge in the next section. The original local scope (that is introduced before the introduction of the introduction) is recovered, and the class object is bound to the class name definition header here (ClassName in the example).

9.3.2 objects

Class objects support two operations: attribute references and instantiation.

Attribute references use the same standard grammar as all attributes in Python: Obj.name. After class object creation, all namings in class namespaces are valid attribute names. So if the class definition is like this:

Class myclass:

"A Simple Example Class"

i = 12345

DEF F (Self):

Return 'Hello World'

Then myclass.i and myclass.f are valid attribute references, which return an integer and a method object, respectively. You can also assign a value for class properties, you can modify it by assigning values ​​to myclass.i. __doc__ is also a valid attribute, returning a class of document strings: "a Simple Example Class". Instantian use function symbols. As long as the class object is considered as a non-parameter function that returns a new class instance. For example (assuming to the previous class):

x = myclass ()

A new class instance is created above and assigns the object to the local variable x.

This instantiation operation ("calls" a class object) to create an empty object. Many classes tend to create objects as initial states. Therefore, the class may define a special way called __init __ (), like this:

DEF __INIT __ (Self):

Self.Data = []

Class define the __init __ () method, the instantiation of the class will automatically call the __init __ () method for the newly created class instance. So in the following example, you can create a new instance:

x = myclass ()

Of course, for elasticity, __init __ () method can have parameters. In fact, the parameter is passed to the instantiation of the class via __init __ (). E.g:

>>> 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.3.3 instance object

What can we use the instance object now? The unique operation of an instance object is the attribute reference. There are two valid attribute names.

The first kind is called data attributes. This is equivalent to "instance variable" or "data member" in C in SmallTalk. Like local variables, data attributes do not require statements, they will generate when they use. For example, if x is a MyClass instance created earlier, the following code will print 16 without any excess residue:

x.counter = 1

While X.counter <10:

x.counter = x.counter * 2

Print X.counter

Del x.counter

The second reference attribute accepted for an instance object is a method. The method is a function of an object. (In Python, the method is not limited to the class instance: Other types of objects can also have a method. For example, the list object has append, insert, remove, sort, however, here, unless otherwise specified, we mention Method for the method species)

The valid name of the instance object relies on its class. Follow the definitions, all (user-defined) function objects in the class corresponding to the method in its instance. So in our example, X..f is an effective method reference because myclass.f is a function. But X.i is not because myclass.i is a function. However, X.f and myclass.f are different - it is a method object, not a function object.

9.3.4 Method Object

Usually the method is to call directly:

X.f ()

In our example, this will return the string 'Hello World'. However, it is not necessary to call the method directly. X.f is a method object that can be called later. For example: xf = x.f

While True:

Print XF ()

Constantly print "Hello World".

What happened when calling a method? You may notice that the previous marked variable is not referenced when calling X.f (), although a parameter is indicated in the F function definition. What happened to this parameter? In fact, if the parameters are missing in the function call, Python will throw an exception - even this parameter doesn't actually use ...

In fact, you may have guessed the answer: The special method of the method is to pass the actual object as the first parameter of the function to the function. In our example, call X.f () is equivalent to myclass.f (x). Typically, a method of n parameters is called, which is equivalent to inserting the object's object into the front of the parameter list, and calls the corresponding function with this list.

If you still don't understand how the method works, you can understand that its implementation may help. When the instance property of the non-data attribute is referenced, it will search it. If this name is confirmed as a valid function object class properties, instance objects and function objects are encapsulated into an abstract object: this is the method object. When calling method objects with a parameter list, it is renewed, constructed a new parameter list with an instance object and the original parameter list, and then the function object calls this new parameter list.

9.4 Some explanations

[Some content may need to be clear ...]

Data properties of the same name will override the method properties, to avoid possible naming conflicts - this may cause difficult BUG in large programs to avoid conflicts with a certain naming convention. Optional conventions include the first letter uppercase of the method, data attribute name prefix lowercase (possibly just a downline), or the method uses the verb and the data attribute uses noun.

Data attributes can be referenced by methods, or they can be called by ordinary users (clients). In other words, the class cannot achieve a pure data type. In fact, there is no way in Python to force hidden data - all basically conventions. (Another method, Python's implementation is written in C, if necessary, can write Python extensions, fully hide the details, and control the access.)

Customers should be careful that the customer may destroy the data consistency maintained by the method because of the free modification of data attributes. It should be noted that customers only need to avoid naming conflicts, they can add data attributes to the instance without affecting the effectiveness of the method - once again emphasized, naming conventions can save a lot of trouble.

There is no shortcut to reference data attributes (and other methods) from ways. I think this in fact adds the readability of the method: even if a rough browsing one method, there will be no chance to confuse local variables and instance variables.

It is used to the first parameter of the method named Self. This is just a convention: For Python, SELF has no special meaning. (However, it should be noted that if this convention is not observed, other Python programmers will be inconvenient when reading your code, and some browsing programs are also developed here.)

Any function object in class properties is defined in class instance as a method. It is not necessary to write a function definition code into a class definition, or you can assign a function object to one variable in the class. E.g:

# Function Defined Outside The Class

DEF F1 (Self, X, Y):

Return MIN (X, X Y)

Class C:

f = f1

DEF G (Self):

Return 'Hello World'

h = g

Now f, g, and h are attributes of class C, references are all function objects, so they are all methods of C instance - h stringent equal to g. It should be noted that this habit usually only confuses the program readers.

The method can call other methods by the method of the SELF parameter:

Class Bag:

DEF __INIT __ (Self):

Self.Data = []

DEF Add (Self, x):

Self.Data.Append (x)

Def AddTwice (Self, X):

Self.Add (x)

Self.Add (x)

The method can reference global naming like reference to a normal function. The global scope associated with the method is a module that contains a class definition. (The class itself will never be used as a global scope!) Although there are very few reason to use global data in the method, there are many legitimate uses: First, the method can call the import global scope function. And methods, you can also call the classes and functions defined therein. Usually, classes containing this method will also be defined in this global scope. In the next section, we will understand what method to reference your own class!

9.5 inheritance

Of course, if a language does not support inheritance, "class" has no significance. The definition of derived class is as follows:

Class DerivedClassName (BaseclassName):

.

.

.

Name BaseClassName (base class name in the example) must be defined in a scope with the derived class. In addition to the class, it is also useful to use an expression. This is very useful when defined in another module:

Class DerivedClassName (MODNAME.BASECLASSNAME):

The execution process of derived class definitions is the same. When constructing a classic object, remember the base class. This is especially useful when parsing attributes: If the property is not found in the class, the base class is searched. If the base class is derived from the other class, this rule will be recursive.

There is no special place for the instantiation of derived classes: DeriveDClassName () (derived class in the field) creates a new class instance. Method references parsed as follows: Search the corresponding class properties, select along the base class, if necessary, if the function object is found, it is legal.

Detective classes may cover the methods of their base. Since the method is called when the method is called in the same object, the method of the base class is not privileged, and when the method of the base class calls the same base class, it may actually finally call the coverage method in the derived class. (For C programmers, all the methods in Python are essentially false.)

The coverage method in the derived class may be the reintegration of the replacement rather than a simple alternative class. There is a simple way to call the base class directly, as long as the call: "BaseclassName.MethodName (Self, Arguments)". Sometimes this is also useful for customers. (Only the base class should be used only when the base class is defined or imported in the same global role domain.)

9.5.1 more inheritance

Python also supports multi-inheritance form. Multi-inherited class definitions are as follows:

Class DerivedClassName (Base1, Base2, Base3):

.

.

.

The only semantics that need to be explained here are rules for parsing class properties. The order is depth priority, from left to right. Therefore, if an attribute is not found in DeriveDClassName (the derived class in the example), then the base1 is searched, then (recursively) searching its base class, if it is finally not found, search for Base2, and so on. (Some people think breresses - Search Base2 and Base3 before searching Base1, it looks more natural. However, if you have a naming conflict between Base1 and Base2, you need to understand this property is defined in BASE1 or Base1's base class. And depth priority does not distinguish attribute inheritance from base classes or direct definitions.)

Obviously, the use of multiple inherits that will not be restricted will bring maintenance nightmare, because Python relies only to rely on the agreement to avoid naming conflicts. Inheriting a very famous question is that the two base classes that derive inheritance are inherited from the same base class. It is not clear that this is meaningful in semantics, but it is easy to think about what consequences that will cause this (instance there will be a separate "instance variable" or data attributes acting on public base class.)

9.6 private variable

Python provides limited support for the private members of the class. Any shape is like __spam (at least two underscores, at the end of multiple single underscale), it is replaced with _classname__spam, removes the ClassName, which is the current-defined scribe, the current class name. This confusing does not care about the syntax position of the identifier, so it can be used to define private examples and class variables, methods, and global variables, and even save other classes as private variables. The confused name is more than 255 characters, it may take a truncation. The truncation does not occur when the class is outside the class, or the class name only contains an underscore.

Named confusion is given to give a simple way to define "private" instance variables and methods in the class, avoiding the exemplary variable definition of derived classes to generate problems, or mix with variables in the outside code. It should be noted that the main purpose of confusion rules is to avoid accidental errors, which is already as private variables that may still be accessible or modified. It is also useful in specific occasions, such as debugging, this is also one of the reasons why this vulnerability has not been blocked (small loopholes: derived class and base class to use the same name to use the private variables.)

It should be noted that the code incoming EXEC, EVAL () or evAlFile () will not call their category as the current class, which is similar to the Global statement, and Global's role is limited to "the same batch" for byte compilation. Code. The same restrictions apply to getAttr (), setattr () and delattr (), and directly quote __dict__.

9.7 supplement

Sometimes similar to the data type of "record" or C "structure" "" "" "" "" "", "it is binds a set of named data items. An empty class definition can be good to implement this:

Class Employee:

PASS

John = Employee () # Create An Empty Employee Record

# Fill The Fields of the Record

John.name = 'john doe'

John.dept = 'computer lab'

John.salary = 1000

A segment of Python code requires a special abstract data structure, usually can be passed into a class, in fact, this is the method of this class. For example, if you have a function that is formatted from the file object, you can define a class with the read () and readline () methods to read the data from the string, then the class The object is incorporated into the aforementioned function as a parameter. Example method objects also have attributes: m.im_self is an object to which the instance method belongs, and M.IM_FUNC is a function object corresponding to this method.

9.8 Anomaly is also a class

User-defined exception can also be class. Use this mechanism to create an extendable exception system.

The following is two new valid (semantic) abnormal throws:

Raise Class, Instance

Raise Instance

In the first form, instance must be a case of Class or its derived class. The second form is the following form:

Raise instance .__ class__, instance

An exception happens If it is the class listed in the abnormal subsequence, or if it is giving birth, then they are consistent (in turn - an exception that occurs, if it is the base listed in the abnormal subsequence Class, they don't match). For example, the following code prints B, C, D:

Class B:

PASS

Class C (b):

PASS

Class D (c):

PASS

For C in [B, C, D]:

TRY:

Raise C ()

Except D:

Print "D"

Except C:

Print "C"

Except B:

Print "B"

It should be noted that if the order of the abnormality is reversed ("Execpt B" is in the forefront), it will print B, B, B - the first matching exception is triggered.

When printing an exception class error message, print the class name first, then a space, a colon, then use the built-in function Str () to convert the class to the full string.

9.9 iterator

Now you may notice that most container objects can be traversed in FOR:

For Element In [1, 2, 3]:

Print Element

For Element In (1, 2, 3):

Print Element

For key in {'one': 1, 'two': 2}:

Print Key

For char in "123":

Print charr

For line in open ("myfile.txt"):

Print Line

This form of access is clear, simple, and convenient. This iterator is usually unparalleled in Python. In the background, the FOR statement calls iter () in the container object. This function returns an iterator object that defines the next () method, which is accessed one by one in the container one by one. When there is no subsequent element, Next () throws a stopiteration exception notification for the FOR statement cycle. The following is an example of its working principle:

>>> s = 'abc'

>>> IT = iter (s)

>>> IT

>>> it.next ()

'a'

>>> it.next ()

'b'

>>> it.next ()

'c'

>>> it.next ()

TRACEBACK (MOST Recent Call Last): File "

", LINE 1, in -toplevel-

IT.next ()

STOPITERATION

Understand the background mechanism of the iterator protocol, you can easily add an iterator behavior to your class. Define a __itor __ () method to return it to an object with a next () method. If this class has defined next (), then __iter __ () only needs to return Self:

>>> Class REVERSE:

"Iterator for looping over a sequence backwards"

DEF __INIT __ (Self, DATA):

Self.Data = DATA

Self.index = LEN (DATA)

DEF __ITER __ (Self):

Return Self

Def next (Self):

if self.index == 0:

Raise StopIitration

Self.index = SELF.INDEX - 1

Return Self.Data [Self.index]

>>> for char in Reverse ('spam'):

Print charr

M

a

p

s

9.10 generator

The generator is a simple and powerful tool for creating an iterator. They write like a regular function, use Yield statements when you need to return data. Each time next () is called, the generator replies the location it detachable (it memory the position of the statement and all the data values). The following example demonstrates that the generator can be created very simple:

>>> DEF Reverse (data):

For Index in Range (Len (DATA) -1, -1, -1):

Yield Data [index]

>>> for char in reverse ('golf'):

Print charr

fly

l

o

G

The previous section describes the class-based iterator, which can be made everything can be made. Because the __iter __ () and next () methods are automatically created, the generator is so simple.

Another key function is that local variables and execution between the two calls are automatically saved. This is easier than manually calling Self.index and Self.Data.

In addition to the automatic method of creating and saving the program status, the StopItemization exception is automatically thrown when the generator is terminated. In summary, these functions make the easiest way to write a regular function to create an iterator.

FootNotes

... Namespaces

! 9.1

There is an exception. The module object has a secret read-only object called

__dict__, it returns a dictionary for implementing module namespace, named

__dict__ is an attribute instead of the global name. Obviously, use it violates the abstract principle implemented by namespace, it should be strictly limited to debugging.

转载请注明原文地址:https://www.9cbs.com/read-4564.html

New Post(0)