Python2.2 New Style Class

Source: Internet
Author: User
Tags builtin

New-style class refers to the class object created from the subclass of Type Meta class or type Meta class, while the traditional class (Classic class) is opposite.

1. builtin-type is now a class
Unlike earlier versions of Python, builtin-types such as int, long, float, complex, list, tuple, and dict are all classes, and their parent classes are both
And generate the object according to the type class (the metadata class is type)

The attributes of these classes are unchangeable. Their _ dict _ attributes are read-only, and only new style custom classes support Value assignment operations.
The _ dict _ attribute remains unchanged, for example:
List. append = List. append
Traceback (most recent call last ):
File "<stdin>", line 1, in?
Typeerror: Can't set attributes of built-in/extension type 'LIST'

List. Answer = 42
Traceback (most recent call last ):
File "<stdin>", line 1, in?
Typeerror: Can't set attributes of built-in/extension type 'LIST'

List. _ dict _ ['answer'] = 42
Traceback (most recent call last ):
File "<stdin>", line 1, in?
Typeerror: object does not support item assignment

Class L (list ):
Pass

L. append = List. append # OK
L. _ dict _ ['append'] = List. append
Traceback (most recent call last ):
File "<interactive input>", line 1, in?
Typeerror: object does not support item assignment

2. builtin-type can be subclass-type
In the old version of Python, when you need to inherit built-in types such as dict, you need to use the following code:
Import userdict
Class defaultdict (userdict. userdict ):
Pass

Now you can inherit from the built-in dict directly, because the current dict is already a class.
Class defaultdict (dict ):

Def _ init _ (self, default = none ):
Dict. _ init _ (Self)
Self. Default = default

Def _ getitem _ (self, key ):
# Key in dict introduced in python2.2
If key in self:
Return dict. _ getitem _ (self, key)
Else:
Return self. default;

3. Use the _ slots _ attribute to restrict instance attributes.
Class person:
Def _ init _ (self, name ):
Self. Name = Name

Person = person ("foo ")
Person. Age = 25 # other attributes can be assigned to the instance person, but in some cases this is not what you want

In this case, the _ slots _ attribute can be used to complete the operation.
Class person (object): # inherit the object
_ Slots __= ['name']

Def _ init _ (self, name ):
Self. Name = Name

Person = person ("foo ")
Person. Age = 25

Traceback (most recent call last ):
File "<interactive input>", line 1, in?
Attributeerror: 'person 'object has no attribute 'age'

Precautions for using _ slots:

You cannot use person. _ slots __=... to define _ slots __
_ Slots _ can be inherited from the parent class (python2.4.1)
The class instance with the _ slots _ definition does not have the _ dict _ attribute, but the class subclass does, unless the subclass also defines _ slots __
Use _ slots __= [] to make the class instance have no instance variables

4. _ getattr _ and _ getattribute _ hook Methods
The _ getstr _ method is called when the instance does not find the attribute, while the _ getattribute _ method is called when the instance finds any attribute.
Note that the _ getattribute _ method is prone to infinite loops. When _ dict _ is used, the _ getattribute _ method is called:
Class A (object ):
Def _ getattribute _ (self, key ):
Print "accessing % R. % s" % (self, key)
# Return self. _ dict _ [Key] Infinite Loop
Return object. _ getattribute _ (self, key)

5. Static Method)
In earlier Python versions, some tips are required to implement the static method function, as shown below:
Import OS
Class command:
Class _ staticcommand:
Def _ call _ (self, command ):
OS. System (command)
# Run is actually an instance of an internal class object. This instance is callable. The key to this method is to define a callable class field.
Run = _ staticcommand ()

If _ name _ = '_ main __':
Command. Run ("DIR/W") # windows
Command. Run ("ls-L") # unix linux

The staticmethod class is provided in python2.2 to conveniently implement static methods.
Import OS
# You do not have to inherit objects or use staticmethod. But as a python trend, try to use objects in future class design.
Class command (object ):
Def run (command ):
OS. System (command)

# Use staticmethod to wrap a function
Run = staticmethod (run)

6. classmethod)
Class method considers the first parameter as a class object, which has no equivalence in Java/C ++.
Class:
# Note: Replace self with CLS because the first parameter is not an instance but a class object.
Def Foo (CLS, X ):
Print "classmethod", CLS, X
Foo = classmethod (FOO)
A. Foo (1), a (). Foo (1)

7. Read/set methods (Java getter/setter)
Object-oriented encapsulation usually requires the use of the read/set method to access object data instead of direct attribute access. What are the advantages of doing so? Get object attributes by using methods
You can have the opportunity to do some additional operations, such as returning cached object attributes, to improve program efficiency or some additional data checks (compare person. Age =-1 ).
And person. setage (-1), it is easy to add logical judgment to the setage method)

# The object must be inherited.
Class person (object ):
Def _ init _ (Self ):
Self. _ age = 0;

Def getage (Self ):
Return self. _ age

Def setage (self, age ):
<Age <150:
Self. _ age = Age
Else:
Raise valueerror, "invalid age"
# Property (fget = none, fset = none, fdel = none, Doc = none)
Age = property (getage, setage)

Person = person ()
Person. Age = 26 # The person. setage is called.
Print person. Age # The person. getage is called.

8. Method resolution order (Mro)
When multiple inheritance occurs, a method query order problem occurs.
Class:
^ Def save (Self ):...
//
//
//
//
Class B Class C:
^ Def save (Self ):...
//
//
//
//
Class D
In classic class, the search order is depth-first, so the search order is D, B, A, and C. Suppose we call the Save method of class D instances,
Obviously, this query order is incorrect, because it ignores the C save method (locate the Save method of a and terminate it)

In New Style Class, the search sequence is D, B, C, A. You can use D. _ Mro _ to view the search sequence.

9. Partner law and super
Here is an example:
Class:
Def M (Self): Print "Save a's data"

Class B ():
Def M (Self): a. m (Self); print "Save B's data"

In the above example, the m method of B reloads the m METHOD OF A, which is common in object-oriented design,
In the M Implementation of B, we explicitly call the m METHOD OF A so that a can save its own State.

This mechanism may be faulty when multiple inheritance occurs, for example
Class A (object ):
Def M (Self): Print "Save a's data"

Class B ():
Def M (Self): a. m (Self); print "Save B's data"

Class C ():
Def M (Self): a. m (Self); print "Save C's data ";

Class D (B, c ):
Def M (Self): B. M (Self); C. M (Self); print "Save D's data"

When calling d (). m (), it is clear that the m method of a will be called twice!
Some may think that we can extract the print statements of A, B, and C, for example _ m, and call B in M of D. _ m (Self), C. _ m (Self),. M (Self )..
However, this structure makes it necessary for the subclass to clearly understand how the parent class does one thing. The coupling degree is very large. Once the parent class changes its method implementation, it is likely to damage
D.

To solve this problem, python uses super call
Class A (object ):
Def M (Self): Print "Save a's data"

Class B ():
Def M (Self): Print "Save B's data"; Super (B, self). m ()

Class C ():
Def M (Self): Print "Save C's data"; Super (C, self). m ()

Class D (B, c ):
Def M (Self): Print "Save D's data"; Super (D, self). m ()

In this case, after calling d (). m (), you can find the print:
Save D's data
Save B's data
Save C's data
Save a's data

Analysis: Super is called through Mro sequence, D. _ Mro __= (D, B, C, A, object)
First, call the m method of d: Print save d's data, then super (D, self). m () finds the m method of B, print save B's data,
In B's super (B, self ). in M (), because the passed self is the instance of D, it is still searched according to the same Mro sequence of D. C is found at this time and printed in the same way.
Save C's data. The self passed by Super (C, self). m () of C is still the instance of D. Find a and call m method of a to terminate.

10. metaclass)
Meta-classes are the classes that generate classes. Meta-classes generate class objects, and class objects generate instance objects.
When executing a Class Definition Statement, the python interpreter first looks for the related Meta class M and then calls M (name, base, dict) to generate a new class.
Object. For example, you can use the following statement to generate a new class object.
# Type is the ancestor of all metadata classes
Foo = type ("foo", (object,), {"getname": Lambda self: "foo-name "})
Use Foo (). getname () to call the Method

Here, the meaning of the three parameters m (name, base, dict) is:
Name: Class Name
Base: The superclass of the generated class object. The null ancestor indicates that no superclass exists.
Dict: class attributes and methods of class objects

So how does the python interpreter look for M meta classes?
A. Use dict [_ metaclass _]
B. If a superclass is defined, use the Meta class of the superclass.
C. Use the global variable _ metaclass __
D. Use the Meta class of classic classes (classtype of the types module) to generate a classic classes
Note that when the defined class has multiple parent classes, if these parent classes are a mixture of new style classes and classic classes, then Python
The first new style classes metadata is used.

Example of metaprogramming: used to automatically add the get/Set Method to the class
Class autoprop (type ):
Def _ init _ (CLS, name, base, dict ):
Super (autoprop, CLS). _ init _ (name, base, dict)
Props = [] # What attributes need to be saved using get/Set
For name in dict:
If name. startswith ("_ GET _") or name. startswith ("_ SET _"):
# For example, if a method named _ get_name is defined in the class, save the name to use GET/set for the name.
Props. append (name [5:])
For name in props:
Fget = getattr (CLS, "_ GET _ % s" % name, none) # obtain the _ get_xxx method object in the class definition.
Fset = getattr (CLS, "_ SET _ % s" % name, none) # obtain the _ set_xxx method object in the class definition.
Setattr (CLS, name, property (fget, fset) # Set get/set for name

Class invertedx:
_ Metaclass _ = autoprop # Use metaclass

Def _ get_x (Self ):
Return-self. _ x

Def _ set_x (self, X ):
Self. _ x =-x

A = invertedx ()
A. X = 12
Print A. X #12
Print A. _ invertedx _ x #-12

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.