Object-oriented design (OOD) does not specifically require an object-oriented programming language. In fact, OOD can be implemented by a pure structured language, such as C. However, if you want to construct a data type with the object nature and characteristics, you need to make more efforts in the program. When a language has built-in OO features, the relationship between object-oriented design and object-oriented programming of OO editing
Object-oriented design (OOD) does not specifically require an object-oriented programming language. In fact, OOD can be implemented by a pure structured language, such as C. But if you want to construct a data type that has the object nature and characteristics, you need to make more efforts in the program. When a language has built-in OO features, OO programming and development will be more convenient and efficient. On the other hand, an object-oriented language does not necessarily force you to write OO programs. For example, C ++ can be considered as "better C", while Java requires that everything is a class. In addition, it also specifies that a source file corresponds to a class definition. However, in Python, classes and OOP are not necessary for routine programming. Although it was designed to be object-oriented from the very beginning and supports OOP in the structure, Python does not limit or require you to write OO code in your application. OOP is a powerful tool, whether you are ready to enter, learn, transition, or turn to OOP, you can control it at will. One of the most important reasons for working with OOD is that it directly provides a way to model and solve real-world problems and situations.
Class
A class is a data structure that can be used to define objects. The latter combines data values with behavior characteristics. Classes are abstract entities in the real world that appear in programming form. An instance is the embodiment of these objects. The analogy is that a class is a blueprint or model used to generate a real object (instance ). Classes can also be derived from similar but different child classes. The concept of classes in programming applies many such features. In Python, the class declaration is very similar to the function declaration. The first line uses a corresponding keyword, followed by a code body defined as it, as shown below:
The code is as follows:
Def functionName (args ):
'Function documentation string' # function document string
Function_suite # function body
Class ClassName (object ):
'Class documentation string' # class document string
Class_suite # class body
Both allow you to create functions, closures, or internal functions in their declarations, as well as methods defined in classes. The biggest difference is that you run a function, and the class will create an object. Class is like a Python container type. Although classes are objects (in Python, everything is an object), they are not implemented by objects when they are being defined.
Create class
The Python class is created using the class keyword. The declaration of a simple class can be a keyword followed by the class name:
The code is as follows:
Class ClassName (bases ):
'Class documentation string' # 'class document string'
Class_suite # class body
A base class is a set of one or more parent classes for inheritance. the class body consists of all declared statements, class member definitions, data attributes, and functions. Classes are usually defined at the top layer of a module so that class instances can be defined at the class level.
Is created anywhere in the source code file.
Declaration and definition
For Python functions, the declaration is no different from the definition class because they are performed at the same time and the definition (class body) follows the declaration (the header line containing the class keyword [header line]). and the optional document string. At the same time, all methods must be defined at the same time. If you are familiar with OOP, note that Python does not support pure virtual functions (such as C ++) or abstract methods (such as in JAVA), which force programmers to define methods in subclasses. As an alternative, you can easily cause NotImplementedError exceptions in the base class methods to achieve similar results.
Class attributes
An attribute is the data or function element of another object. it can be accessed through the familiar period attribute identification method. Some Python types, such as complex numbers, have data attributes (real and virtual), while others, such as lists and dictionaries, have methods (function attributes ).
An interesting thing about attributes is that when you are accessing an attribute, it is also an object with its own attributes and can be accessed, which leads to an attribute chain, for example, myThing, subThing, subSubThing. and so on.
Class data attributes
The data attribute is only a variable of the defined class. They can be used after the class is created like any other variable, and they are either updated by the method in the class or elsewhere in the main program.
This type of attribute is familiar to OO programmers, namely static variables or static data. They indicate that the data is bound to the class object to which they belong and does not depend on any class instance. If you are a Java or C ++ programmer, this type of data is equivalent to adding the static keyword before a variable declaration. Static members are generally used to track class-related values only.
The following example shows how to use the class data attribute (foo ):
The code is as follows:
>>> Class c (object ):
Foo = 100.
>>> Print c. foo
100
>>> C. foo + = 1
>>> C. foo
101
Method
The code is as follows:
>>> Class MyClass (object ):
Def myNoActionMethod (self ):
Pass
>>> Mc = MyClass ()
>>> Mc. myNoActionMethod ()
Any call to myNoActionMethod itself like a function will fail:
The code is as follows:
>>> MyNoActionMethod () Traceback (innermost last ):
File" ", Line 1, in?
MyNoActionMethod () NameError: myNoActionMethod
Even the class object fails to call this method.
The code is as follows:
>>> MyClass. myNoActionMethod () Traceback (innermost last ):
File" ", Line 1, in?
MyClass. myNoActionMethod ()
TypeError: unbound method must be called with class
Instance 1st argument
Binding (binding and non-binding methods)
To be consistent with OOP conventions, Python strictly requires that methods cannot be called without instances. This restriction is the binding concept described in Python. here, the method must be bound (to an instance) to be called directly. A non-bound method may be called, but the instance object must be explicitly specified to ensure the call is successful. However, methods are inherent attributes of their classes regardless of whether they are bound, even if they are almost always called through instances.
Determines the attributes of a class.
You need to know the attributes of a class in two ways. The simplest is to use the dir () built-in function. In addition, the dictionary attribute _ dict __of the category class is used, which is one of the special attributes of all classes.
Let's take a look at the following example:
The code is as follows:
>>> Class myclass (object ):
'Myclass definition '# class definition
MyVersion = '1. 1' # static data
Def showVesion (self): # method
Print myclass. myVersion
>>> Dir (myclass)
Running result:
The code is as follows:
['_ Class _', '_ delattr _', '_ dict _', '_ doc __', '_ format _', '_ getattribute _', '_ hash _', '_ init _', '_ module __', '_ new _', '_ reduce _', '_ performance_ex _', '_ repr _', '_ setattr __', '_ sizeof _', '_ str _', '_ subclasshook _', '_ weakref _', 'myversion', 'showvesion ']
Usage:
The code is as follows:
>>> Myclass. _ dict __
Dict_proxy ({'_ module _': '_ main _', 'showvesion ': , '_ Dict _':, 'myversion': '1. 1', '_ weakref _':, '_ doc _': 'myclass class definition '})
As you can see above, dir () returns only a list of names of the object's attributes, while _ dict _ returns a dictionary, and its key (keys) is the attribute name, values is the data value of the corresponding property object.
The results also show two familiar attributes in the MyClass class, showMyVersion and myVersion, and some new attributes. These attributes __doc _ and _ module _ are special class attributes of all classes (in addition, _ dict __).. The built-in vars () function accepts class objects as parameters and returns the content of The _ dict _ attribute of the class.
Special class attributes
For any class C, the table shows all the special properties of Class C:
C. _ name _ Class C name (string)
C. _ doc _ Class C document string
Tuples of all parent classes of C. _ bases _ Class C
C. _ dict _ Class C attributes
C. _ module _ Class C definition module (added in version 1.5)
C. _ class C class (only in the new class)
The code is as follows:
>>> Myclass. _ name __
'Myclass'
>>> Myclass. _ doc __
'Myclass definition'
>>> Myclass. _ bases __
( ,)
>>> Print myclass. _ dict __
{'_ Module _': '_ main _', 'showvesion ': , '_ Dict _':, 'myversion': '1. 1', '_ weakref _':, '_ doc _': 'myclass class definition '}
>>> Myclass. _ module __
'_ Main __'
>>> Myclass. _ class __
Instance
If a class is a data structure definition type, the instance declares a variable of this type. An instance is an object that is mainly used at runtime. classes are instantiated to obtain instances. the instance type is the class to be instantiated.
Initialization: creates an instance by calling a class object.
Python is simpler. Once a class is defined, it is easier to create an instance than to call a function. The implementation of instantiation can use the function operator, as shown below:
>>> Class MyClass (object): # define class definition class
Pass
>>> Mc = MyClass () # instantiate class initialization class
_ Init _ () "constructor" method
When a class is called, the first step of instantiation is to create an instance object. Once an object is created, Python checks whether the _ init _ () method is implemented. By default, if no special method _ init _ () is defined (or overwritten), no special operation is performed on the instance. for any specific operation, the programmer must implement _ init _ () to overwrite its default behavior.
If _ init _ () is not implemented, its object is returned and the instantiation process is complete.
If _ init _ () has been implemented, it will be called and the instance object will be passed in as the first parameter (self), just like a standard method call. When a class is called, any parameters passed in are handed over to _ init __(). In reality, you can think of the call to create an instance as a call to the constructor.
_ New _ () "constructor" method
Compared with _ init _ (), the __new _ () method is more like a real constructor. You need a way to instantiate an immutable object, such as a derived string, number, and so on. In this case, the interpreter calls the _ new _ () method of the class, a static method, and the input parameters are generated during the class instantiation operation. _ New _ () will call _ new _ () of the parent class to create an object (up proxy ). _ New _ () must return a valid instance.
_ Del _ () "parser" method
Similarly, there is a special destructor method named _ del __(). However, because Python has a garbage collection mechanism (dependent on reference count), this function will not be executed until all references of the instance object are cleared. The deconstruct in Python provides special processing functions before an instance is released. they are generally not implemented because instances are rarely explicitly released.
Note: Python does not provide any internal mechanism to track how many instances of a class have been created, or to record what these instances are. If you need these functions, you can explicitly add some code to the class definition or _ init _ () and _ del. The best way is to use a static member to record the number of instances. It is dangerous to trace instance objects by saving their references, because you must properly manage these references. Otherwise, your references may not be released (because there are other references )! Let's look at the following example:
The code is as follows:
>>> Class instCt (object ):
Count = 0
Def _ init _ (self ):
InstCt. count + = 1
Def _ del _ (self ):
InstCt. count-= 1
Def howMany (self ):
Return instCt. count
>>> A = instCt ()
>>> B = instCt ()
>>> B. howMany ()
2
>>> A. howMany ()
2
>>> Del B
>>> A. howMany ()
1
>>> Del
>>> InstCt. count
0
Instance attributes
You can set the attributes of an instance at any time after the instance is created, or in the code that can access the instance. The constructor _ init () _ is one of the key points for setting these attributes.
Being able to create instance attributes at runtime is one of the excellent features of the Python class. Python is not only a dynamic type, but also allows dynamic creation of these object attributes at runtime. This feature is incredibly appealing.
Hand. Exercise caution when creating such an attribute. One drawback is that the attribute is created in the condition statement. if the condition statement block is not executed, the attribute does not exist, and you try to access these attributes in the code below, an error occurs.
Default parameters provide default instance installation
In practical applications, _ init _ () with default parameters provides an effective way to initialize the instance. In many cases, the default value indicates the most common case for setting instance properties. if the default value is provided, we do not need to explicitly pass the value to the constructor.
The code is as follows:
> Class program roomc1c (object ):
'Hotel room rate calculate'
Def _ init _ (self, rt, sales = 0.085, rm = 0.1 ):
'''Specify the default arguments:
Sales tax = 8.5% and room tax = 10% '''
Self. salesTax = sales
Self. roomTax = rm
Self. roomRate = rt
Def calcTotal (self, days = 1 ):
'Calculate total: default to daily rate'
Daily = round (self. roomRate * 14*(1 + self. roomTax + self. salesTax), 2)
Return float (days) * daily
>>> Sfo = hotelroomc1c (299)
>>> Sfo. calcTotal ()
4960.41
>>> Sfo. calcTotal (2)
9920.82
>>> Sea = Hangzhou roomc1c (189, 0.086, 0.085)
>>> Sea. calcTotal ()
3098.47
>>> Sea. calcTotal (4)
12393.88
All the flexibility of functions, such as default parameters, can also be applied to methods. The variable length parameter is also a good feature during instantiation.
_ Init _ () should return None
When a class object is called using function operators, a class instance is created. that is to say, the object returned by such a call process is an instance. the following example shows that:
The code is as follows:
>>> Class MyClass (object ):
Pass
>>> Mc = MyClass ()
>>> Mc
<__Main _. MyClass object at 0x0134E610>
If the constructor is defined, it should not return any objects, because the instance object is automatically returned after the instantiation call. Correspondingly, __init _ () should not return any object (should be None); otherwise, a conflict may occur because only instances can be returned. Trying to return any other object other than None will cause TypeError exception:
The code is as follows:
>>> Class MyClass:
Def _ init _ (self ):
Print 'initialized'
Return 1
>>> Mc = MyClass ()
Initialized
Traceback (most recent call last ):
File" ", Line 1, in
Mc = MyClass ()
TypeError: _ init _ () shoshould return None
View instance attributes
The built-in function dir () can display class attributes and print all instance attributes:
The code is as follows:
>>> C = C ()
>>> C. foo = 'hes'
>>> C. bar = 'Isa'
>>> Dir (c)
['_ Class _', '_ delattr _', '_ dict _', '_ doc __', '_ format _', '_ getattribute _', '_ hash _', '_ init _', '_ module __', '_ new _', '_ reduce _', '_ performance_ex _', '_ repr _', '_ setattr __', '_ sizeof _', '_ str _', '_ subclasshook _', '_ weakref _', 'bar', 'foo']
Similar to a class, an instance also has a special attribute _ dict _ (which can be obtained by calling vars () and passing in an instance). It is a dictionary composed of instance attributes:
The code is as follows:
>>> C. _ dict __
{'Foo': 'hes', 'bar': 'Isa '}
Special instance attributes
The instance has only two special attributes. For any object I:
I. _ class _ instantiate the class of I
I. _ dict _ I attributes
The code is as follows:
>>> Class C (object ):
Pass
>>> C = C ()
>>> Dir (c)
['_ Class _', '_ delattr _', '_ dict _', '_ doc __', '_ format _', '_ getattribute _', '_ hash _', '_ init _', '_ module __', '_ new _', '_ reduce _', '_ performance_ex _', '_ repr _', '_ setattr __', '_ sizeof _', '_ str _', '_ subclasshook _', '_ weakref _']
>>> C. _ dict __
{}
>>> C. _ class __
>>># You can see that c has no attributes.
>>> C. foo = 1
>>> C. bar = 'Ewe'
>>> '% D can of % s please' % (c. foo, c. bar)
'1 can of ewe please'
>>> C. _ dict __
{'Foo': 1, 'bar': 'Ewe '}
Built-in type attributes
The built-in type is also a class. you can also use dir () to create an internal type. like any other object, you can get a list containing its attribute name:
The code is as follows:
>>> X = 2 + 2.4j
>>> X. _ class __
>>> Dir (x)
['_ Abs _', '_ add _', '_ class _', '_ coerce __', '_ delattr _', '_ p _', '_ pmod _', '_ doc _', '_ eq __', '_ float _', '_ floorp _', '_ format _', '_ ge _', '_ getattribute __', '_ getnewargs _', '_ gt _', '_ hash _', '_ init _', '_ int __', '_ le _', '_ long _', '_ lt _', '_ mod _', '_ mul __', '_ ne _', '_ neg _', '_ new _', '_ nonzero _', '_ pos __', '_ pow _', '_ radd _', '_ rp _', '_ rpmod _', '_ reduce __', '_ performance_ex _', '_ repr _', '_ rfloorp _', '_ rmod _', '_ rmul __', '_ rpow _', '_ rsub _', '_ rtruep _', '_ setattr _', '_ sizeof __', '_ str _', '_ sub _', '_ subclasshook _', '_ truep _', 'conjugate', 'imag ', 'Real']
Failed to access _ dict _ because this attribute does not exist in the internal creation type.
Instance attributes vs class attributes
The class attribute is only the data value related to the class. it is different from the instance attribute and has nothing to do with the class attribute. These values are referenced as static members. even if the class is called multiple times, their values remain unchanged. In any case, static members do not change their values because of the instance, unless they explicitly change their values in the instance. Both classes and instances are namespaces. The class is the namespace of the class attribute, and the instance is the instance attribute.
Some other aspects of class attributes and instance attributes need to be pointed out. You can use a class to define the class attributes. If an instance does not have an attribute of the same name, you can also use an instance to access the instance.
Category attributes
Class attributes can be accessed through classes or instances. In the following example, class C is created with a version attribute, so it is natural to access it through class objects, such as C. version.
The code is as follows:
>>> Class C (object ):
Version = 2
>>> C = C ()
>>> C. version
2
>>> C. version
2
>>> C. version + = 2
>>> C. version
4
>>> C. version
4
Exercise caution when selecting the category attribute from the instance
Like a common Python variable, any assignment to an instance attribute creates an instance attribute (if it does not exist) and assigns a value to it. If an attribute with the same name exists in the class property, the side effect is generated.
The code is as follows:
>>> Class Foo (object ):
X = 1
>>> Foo = Foo ()
>>> Foo. x
1
>>> Foo. x = 2
>>> Foo. x
1
After del is used
The code is as follows:
>>> Del foo. x
>>> Foo. x
1
Static members, as their names say, do not pick up the progress of the entire instance (and its attributes) (so they are independent of the instance ). At the same time, when an instance is created after the class attribute is modified, the updated value will take effect. Modifying the class attributes will affect all instances:
The code is as follows:
>>> Class C (object ):
Spam = 11
>>> C1 = C ()
>>> C1.spam
11
>>> C. spam + = 2
>>> C. spam
13
>>> C1.spam
13
>>> C2 = C ()
>>> C2.spam
13
>>> Del c1
>>> C. spam + = 3
>>> C2.spam
16
As we can see above, it is very dangerous to use instance attributes to try to modify class attributes. The reason is that the instance has its own attribute set. there is no clear method in Python to indicate that you want to modify the class attributes with the same name. to modify the class attributes, you need to use the class name instead of the instance name.
Static methods and class methods
Static methods and class methods are introduced in Python2.2. It can be used in both the classic and new-style classes. A pair of built-in functions are introduced to declare "tag", "cast", or "convert" for a method that is part of the class definition) is one of the two types of methods.
Now let's take a look at some examples of creating static methods and class methods in classic classes:
The code is as follows:
>>> Class TestStaticMethod:
Def foo ():
Print 'calling static method foo ()'
Foo = staticmethod (foo)
>>> Class TestClassMethod:
Def foo (cls ):
Print 'calling class method foo ()'
Print 'foo () is part of class: ', cls. _ name __
Foo = classmethod (foo)
The corresponding built-in functions are converted to their corresponding types and assigned to the same variable name. If you do not call these two functions, both of them will generate errors in the Python compiler and display the general method declaration that requires self.
The code is as follows:
>>> Tsm = TestStaticMethod ()
>>> TestStaticMethod. foo ()
Calling static method foo ()
>>> Tsm. foo ()
Calling static method foo ()
>>> Tcm = TestClassMethod ()
>>> TestClassMethod. foo ()
Calling class method foo ()
Foo () is part of class: TestClassMethod
>>> Tcm. foo ()
Calling class method foo ()
Foo () is part of class: TestClassMethod
Use the Function modifier:
New features added in Python2.4. You can use it to apply a function to another function object, and the new function object is still bound to the original variable. We just need it to sort out the syntax. By using decorators, we can avoid re-assigning values as above:
The code is as follows:
>>> Class TestStaticMethod:
@ Staticmethod
Def foo ():
Print 'calling static method foo ()'
>>> Class TestClassMethod:
@ Classmethod
Def foo (cls ):
Print 'calling class method foo ()'
Print 'foo () is part of class: ', cls. _ name __