In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
In this issue, the editor will bring you about the principles of class, base class, polymorphism and cancellation of base class in python. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.
I saw "python's class, base class, polymorphism, canceling base class code" a long time ago, and now I want to find that example, but unfortunately, I can't find it again! Forget it, collect what you already know and replenish it when you see it later!
_ _ bases__ is a tuple (which may be None or unary), including its base class, which appears in the order in which they are listed in the base class list
Def classic_lookup (cls, name):
"Look up name in cls and its base classes."
If cls.__dict__.has_key (name):
Return cls.__dict__ [name]
For base in cls.__bases__:
Try:
Return classic_lookup (base, name)
Except AttributeError:
Pass
Raise AttributeError, name
-
Define
Python's Class is quite special, which is quite different from the static language type definition we are used to.
1. Initialization is done using a method called _ _ init__.
two。 Use a method called _ _ del__ to complete a similar parsing operation.
3. All instance methods have a self parameter to pass the current instance, similar to this.
4. You can use _ _ class__ to access type members.
> class Class1:
Def _ init__ (self):
Print "initialize..."
Def test (self):
Print id (self)
> a = Class1 ()
Initialize...
> > a.test ()
13860176
> > id (a)
13860176
Class has some special properties that make it easy for us to get some additional information.
> > class Class1 (object):
"Class1 Doc."
Def _ init__ (self):
Self.i = 1234
> Class1.__doc__ # type help information
'Class1 Doc.'
> Class1.__name__ # type name
'Class1'
> the module where the Class1.__module__ # type resides
'_ _ main__'
The base class inherited by the Class1.__bases__ # type
()
>
> Class1 (). _ _ class__ # type
>
'_ _ main__'
>
{'irie: 1234}
Inherit
Python supports multiple inheritance, but there are a few points to note:
1. The base class _ _ init__ / _ _ del__ needs to display the call.
two。 The invocation of inherited methods is related to the order of base class declaration.
> class Base1:
Def _ init__ (self):
Print "Base1"
Def test (self):
Print "Base1 test..."
> class Base2:
Def _ init__ (self):
Print "Base2"
Def test (self):
Print "Base2 test..."
> class Class1 (Base2, Base1):
Def _ init__ (self):
Base1.__init__ (self)
Base2.__init__ (self)
Print "Class1"
> a = Class1 ()
Base1
Base2
Class1
> > a.test ()
Base2 test...
Members
Python Class also contains both type and instance members.
> class Class1:
I = 123 # Class Field
Def _ init__ (self):
Self.i = 12345 # Instance Field
> print Class1.i
one hundred and twenty three
> > print Class1 (). I
12345
There are several very "special"rules" to pay attention to.
(1) We can access type members through instance references. So in the following example, self.i actually points to Class1.i until we add a new member I to the instance.
> class Class1:
I = 123
Def _ init__ (self):
Print self.i
Print hex (id (self.i))
> hex (id (Class1.i)) # display Class1.i
'0xab57a0'
> a = Class1 () # to create a Class1 instance, we will find that self.i actually points to Class1.i.
one hundred and twenty three
0xab57a0
> Class1.__dict__ # shows Class1 members
{'module__':: 123,' _ _ module__':'_ _ main__','_ _ doc__': None,'_ _ init__':}
> a.displaying instance members
{}
> A.I = 123456789 # add a member I to the instance
> hex (id (a.i)) # shows the address of the new instance member
'0xbbbb674'
> a.displaying instance members
{'irie: 123456789}
(2) to call the inner method of the type, you need to omit the self parameter.
> class Class1:
Def _ init__ (self):
Self.__test ("Hello, World!")
Def _ _ test (self, s):
Print s
> > Class1 ()
Hello, World!
We can add "_" before the member name to make it a private member.
> class Class1:
_ I = 123
Def _ init__ (self):
Self.__x = 0
Def _ test (self):
Print id (self)
> Class1.i
Traceback (most recent call last):
File "", line 1, in
Class1.i
AttributeError: class Class1 has no attribute 'i'
> Class1 (). _ x
Traceback (most recent call last):
File "", line 1, in
Class1 (). _ x
AttributeError: Class1 instance has no attribute'_ x'
> Class1 (). Test ()
Traceback (most recent call last):
File "", line 1, in
Class1 () .test ()
AttributeError: Class1 instance has no attribute 'test'
In fact, this is just a rule, not a restriction on the compiler. We can still use special syntax to access private members.
> Class1._Class1__i
one hundred and twenty three
> a = Class1 ()
> a._Class1__x
0
> > a._Class1__test ()
13860376
In addition to static (type) fields, we can also define static methods.
> class Class1:
@ staticmethod
Def test ():
Print "static method"
> > Class1.test ()
Static method
From a design point of view, you may prefer to use property instead of field.
> class Class1:
Def _ init__ (self):
Self.__i = 1234
Def getI (self): return self.__i
Def setI (self, value): self.__i = value
Def delI (self): del self.__i
I = property (getI, setI, delI, "Property I")
> a = Class1 ()
> a.I
1234
> > A.I = 123456
> a.I
123456
If it's just readonly property, you can do it in another way.
> class Class1:
Def _ init__ (self):
Self.__i = 1234
@ property
Def I (self):
Return self.__i
> a = Class1 ()
> a.I
1234
The function of C# indexer can be realized with _ _ getitem__ and _ _ setitem__.
> class Class1:
Def _ init__ (self):
Self.__x = ["a", "b", "c"]
Def _ _ getitem__ (self, key):
Return self.__ x[key]
Def _ _ setitem__ (self, key, value):
Self.__ x [key] = value
> a = Class1 ()
> a [1]
'b'
> a [1] = "xxxx"
> a [1]
'xxxx'
Heavy load
Python supports some special methods and operator overloading.
> class Class1:
Def _ init__ (self):
Self.i = 0
Def _ str__ (self):
Return "id=%i"% id (self)
Def _ _ add__ (self, other):
Return self.i + other.i
> a = Class1 ()
> > A.I = 10
> > str (a)
'id=13876120'
> b = Class1 ()
> > b.I = 20
> a + b
thirty
By overloading "_ _ eq__", we can change the behavior of the "= =" operator.
> class Class1:
Pass
> a = Class1 ()
> b = Class1 ()
> a = = b
False
> class Class1:
Def _ _ eq__ (self, x):
Return True
> a = Class1 ()
> b = Class1 ()
> a = = b
True
Open Class
This is a controversial topic. In Python, we can add new members to a type or object at any time.
1. Add a field
> class Class1:
Pass
> a = Class1 ()
> > a.x = 10
> a.x
ten
> > dir (a)
['_ _ doc__','_ _ module__','x']
> b = Class1 ()
> > dir (b)
['_ _ doc__','_ _ module__']
> del a.x
> > dir (a)
['_ _ doc__','_ _ module__']
two。 Add method
> class Class1:
Pass
> def test ():
Print "test"
> > def hello (self):
Print "hello", id (self)
> a = Class1 ()
> > dir (a)
['_ _ doc__','_ _ module__']
> Class1.test = test
> > dir (a)
['_ _ doc__','_ _ module__', 'test']
> b = Class1 ()
> > dir (b)
['_ _ doc__','_ _ module__', 'test']
> a.hello = hello
> > a.hello (a)
Hello 13860416
> > dir (a)
['_ _ doc__','_ _ module__', 'hello',' test']
> > dir (b)
['_ _ doc__','_ _ module__', 'test']
3. Change the existing method
> class Class1:
Def test (self):
Print "a"
> > def test (self):
Print "b"
> Class1.test = test
> Class1 (). Test ()
B
In addition, there are several built-in functions that make it easy for us to operate at runtime.
> hasattr (a, "x")
False
> > a.x = 10
> getattr (a, "x")
ten
> setattr (a, "x", 1234)
> a.x
1234
How is Python Open Class implemented? Let's take a look at the following code.
> class Class1:
Pass
> a = Class1 ()
> a. Thank you very much
{}
> > a.x = 123
> a. Thank you very much
{'xdye: 123}
> a.x
one hundred and twenty three
> a.test = lambda I: I + 1
> > a.test (1)
two
> a. Thank you very much
{'test':,' Xerox: 123}
Originally, Python Class objects or types store member information through the built-in member _ _ dict__.
We can also intercept access to members by overloading _ _ getattr__ and _ _ setattr__, noting that _ _ getattr__ is called only when accessing members that do not exist.
> class Class1:
Def _ _ getattr__ (self, name):
Print "_ _ getattr__"
Return None
Def _ _ setattr__ (self, name, value):
Print "_ _ setattr__"
Self.__dict__ [name] = value
> a = Class1 ()
> a.x
_ _ getattr__
> > a.x = 123
_ _ setattr__
> a.x
one hundred and twenty three
If the type inherits from object, we can use _ _ getattribute__ to intercept all fetch operations (including non-existent members).
Note that do not use "return self.__dict__ [name]" to return the result in _ _ getattribute__, because the access to "self.__dict__" will also be intercepted by _ _ getattribute__, resulting in infinite recursion to form an endless loop.
> > class Class1 (object):
Def _ _ getattribute__ (self, name):
Print "_ _ getattribute__"
Return object.__getattribute__ (self, name)
> a = Class1 ()
> a.x
_ _ getattribute__
Traceback (most recent call last):
File "", line 1, in
A.x
File "", line 4, in _ _ getattribute__
Return object.__getattribute__ (self, name)
AttributeError: 'Class1' object has no attribute' x'
> > a.x = 123
> a.x
_ _ getattribute__
one hundred and twenty three
-
_ _ bases__ is the parent class, which refers to the inheritance relationship.
_ _ class__ is the "class / type" of an object, which refers to the type / instance relationship.
In 06-1-10, Shhgs wrote:
>
> mixin
>
> class A (object):
> pass
>
> class B:
> def f (self):
> print "B.F ()"
>
> A.Basies bases__ _ + = (B,) # as if this is what I'm looking for, can I take the tuple. _ _ tuple? The base classes in list are deleted and added at any time! He he! The function is super strong!
>
> a = A ()
> a.f ()
-
When I started to learn python, I read some tutorials and materials, and I felt that I was relatively fragmented in the aspect of object-oriented programming, and I always felt beside the point. It wasn't until I saw the English version of Python in the Nutshell from Oreilly, especially Charpter5: Object-Oriented Python, that I began to understand a little bit. In this book, the arrangement of the chapters is very reasonable, and it not only teaches you how but also teaches you why, which benefits a lot.
In the process of reading, I write down some things one after another, have part of the translation of the book, have my own experience and test code.
In translation, a small part of the translation is direct translation, most of them are actually just their own free translation, but also added some of their own instructions. After all, my goal is to understand the problem, and it's a mystery that I don't want to do so much hard translation. So I want to merge it into one, so I have this article. The arrangement of the article is basically the same as Python in the Nutshell's Charpter5, but the content is much shorter.
Wilson Sun
-
Python is an object-oriented programming language. However, unlike other object-oriented languages, python does not force you to write programs in an object-oriented way, it also allows you to write modules, functions, etc., in a process-oriented way.
1.1 Classical objects (classic class)
In version 2. 1 and earlier, python can only be programmed with the object model of Classic objects. In versions 2.2 and 2.3 of python, Classic objects are also the default object model.
1.1.1 some characteristics of classic objects:
You can call an object in the same way as a function. Once called, an instance of the object is created.
You can name the attributes inside the object as you like.
The l property can be a data type or a function type.
If the property (attribute) is a function type, think of it as a method (method) of the object.
L python specifies a special naming method for the function, using two underscores around the function name, for example: _ _ methodName__.
L objects can be inherited.
1.1.2 object declaration
The syntax for declaring an object:
Class classname [(base-classes)]:
Statement (s)
Classname is the function name.
The value of base-classes must be an object, separated by a comma, which is equivalent to a superclass in java.
Inheritance relationships can be passed. If C1 is a subclass of c2 and c2 is a subclass of c3, then C1 is also a subclass of c3.
The built-in function issubclass (C1, C2) can determine the inheritance relationship. If C1 is a subclass of c2, then the function returns true. Since any class is treated as a subclass of itself, if there is a class C, then issubclass (C _ Magi C) returns true.
The difference between Def declaration syntax and class declaration syntax:
When Def declares, the colon must be preceded by parentheses, even if it does not have any parameters, but when class declares, you need to write its base class in parentheses only if class has its base class (base class).
1.1.3 object body
1.1.3.1 Properties inside the object
Call its properties inside the object and write its property name directly, such as:
Class C3:
X = 23
Y = x + 22 # must use just x, not C3.x
However, if you define a method inside an object, to call other properties in the object in the method, you need to write the full name of the property, such as:
Class C4:
X = 23
Def amethod (self):
Print C4.x # must use C4.x, not just x
Some of these properties are implicitly declared when the object is declared.
Name of _ _ name__: class
_ _ base__:tuple object, placing all base classes of the object
_ _ dict__:dict object, placing all properties of the object
For example, if there is an attribute S inside object C, then C.S=x is equivalent to C. _ dict_ _ ['S'] = x
1.1.3.2 functions inside the object
The function inside the object is written in the same way as the ordinary function, except that the first parameter of the function should be written as self, such as:
Class C5:
Def hello (self):
Print "Hello"
1.1.3.3 Private variables
To declare a private variable, you only need to precede the variable name with two underscores. For example, if there is a private variable user inside class C, it should be declared as: _ _ user.
In fact, when python compiles, it changes _ _ user to _ C__user (that is, the format of _ ClassName__VariableName).
Variables that begin with an underscore are treated as private variables, whether or not they are inside the object.
1.1.4 instance
Review the first point in the previous "some characteristics of Classic objects": "you can call an object like a call function." When you create an instance, this is how it is created:
AnInstance = C5 ()
1.1.4.1 _ _ init_ _
If an object has or inherits a _ _ init_ _ method, the _ _ init_ _ method will be called automatically when the object is called (instantiated using words on java).
The _ _ init_ _ method cannot have a return value, and if you must jump out or return, it can only return None.
For example:
Class C4:
Def _ init__ (self):
Return 'sss'
A = C4 ()
Python will report an error:
Traceback (most recent call last):
File "", line 1, in-toplevel-
A = C4 ()
TypeError: _ _ init__ () should return None
The main purpose of the _ _ init_ _ method is to assign values to the properties of the object when the object instance is created. Doing so increases the readability of the program. If there is no _ _ init_ _ inside the object, then you cannot call the object with any parameters.
1.1.4.2 Properties in the instance
Use a dot (.) to access the properties in the instance.
Even if an object has been instantiated, you can still add arbitrary properties to an instance and assign values to it.
Class C7: pass
Z = C7 ()
Z.x = 23
After the instance is created, two properties are automatically added to the instance:
_ _ class_ _: the object to which the instance belongs
_ _ dict_ _: all properties of the instance (the properties of the instance itself and the properties of the object to which it belongs)
Such as:
Class C6:
Def _ init_ _ (self,n):
Self.x = n
A = C6 (234)
A.y=213213
A.__dict__
# execution result: {'yearly: 213213,' x: 234}
1.1.4.3 Factory function
Think of the factory pattern (Factory), which is the most frequently used design pattern, which is used to create instances of objects. In python, the most direct way to implement the factory pattern seems to be to return different instances with _ _ init_ _, but unfortunately,_ _ init_ _ can only return None at most. So the best way to implement the factory pattern is to write a function that returns different instances, which can be called a factory function (Factory Function).
As in the following example, appropriateCase is a factory function.
Class SpecialCase:
Def amethod (self): print "special"
Class NormalCase:
Def amethod (self): print "normal"
Def appropriateCase (isnormal=1):
If isnormal: return NormalCase ()
Else: return SpecialCase ()
Aninstance = appropriateCase (isnormal=0)
Aninstance.amethod ()
1.1.5 attribute reference
Suppose x is an instance of object C, how do you find its value when referencing x.name? To sum up in the simplest terms, from small to large, from near to far, look up the value of name in turn.
To be more specific, look for it in the following way:
If x.name is the key in x._ _ dict_ _, then return x._ _ dict_ _ ['name'] (find yourself)
Otherwise, find the key in C. _ _ dict_ _. If yes, return C. _ _ dict_ _ ['name'] (find the object to which you belong)
Otherwise, look for the base class of C and continue to follow the above two steps in C. _ _ bases_ _ (find the base class of the object to which you belong)
Otherwise, throw an exception: AttributeError
1.1.6 binding and unbinding of methods (Bound and Unbound)
The above mentioned property reference, method binding and unbinding actually involves the problem of method reference. Method is actually implemented using functions. When a method is referenced, instead of directly returning its corresponding function, the function is loaded into the bound or unbound method.
The difference between bound and unbound is that bound associates a specific function with a specific instance, while unbound does the opposite.
If there is no attribute with the same name, you can observe its binding state by using the function name directly (without parentheses after the function name).
Suppose you have object C and instance x:
Class C:
A = 1
Def g (self): print "method g in class C"
X = C ()
Print x.g
# execution result:
Print C.g
# execution result:
The above execution results show that x.g is bound to the C.G () function, so executing x.g () returns a result, while C.g is not bound, so executing C.G () has no result.
1.1.6.1 details about unbound
In an unbound state, when a function is referenced, it actually returns the unbound method, which contains the function inside. The Unbound method has three read-only properties
Im_class: the object in which the referenced function resides
Im_func: referenced function
Im_self: always None
Unbound methods can also be called, and the instance name of the im_class object needs to be taken as the first argument, and the function of im_func will be returned.
For example, the above C.g () has no result, but you can execute C.G (x), x is an instance of C, and you can get the correct execution result of the C.G () function.
1.1.6.2 describe binding in detail
When x.g () is executed, the bound method is returned. The bound method is similar to the unbound method, with three read-only properties: im_class,im_func,im_self, but the difference is that the value of im_self is x.
1.1.7 inheritance and overloading
From the lookup method of "attribute reference" mentioned earlier, it is not difficult to see how python inheritance is implemented. If x is an instance of C, when calling x.g (), python first looks for g in x.g _ dict_ _, looks for C. _ dict_ _ if not, and looks for C. _ base_ _ g if there is no more. If the base class of C is placed in C _ _ base_ _, object inheritance is realized. With such a mechanism, overloading is also achieved.
1.1.7.1 superclass agent
In the subclass, it is possible to use the properties of the superclass, so it is necessary to use the superclass proxy mechanism, which is actually calling the superclass function in the way of unbound. For example:
Class Base:
Def greet (self, name): print "Welcome", name
Class Sub (Base):
Def greet (self, name):
Print "Well Met and"
Base.greet (self, name)
X = Sub ()
X.greet ('Alex')
The superclass proxy is often used in the _ _ init_ _ method, because in python, the _ _ init_ _ method in the subclass's _ init_ _ method is not automatically called, so you need to use this superclass proxy mechanism to call it manually.
These are the principles of class, base class, polymorphism and cancellation of base class in python shared by Xiaobian. If you happen to have similar doubts, you might as well refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.