Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Summary of Python knowledge points

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces the relevant knowledge of "summary of Python knowledge points". In the operation of actual cases, many people will encounter such a dilemma. Then let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

1. Why use descriptors?

Suppose you are writing a performance management system for your school, and you, who do not have much coding experience, may write like this.

Class Student: def _ _ init__ (self, name, math, chinese, english): self.name = name self.math = math self.chinese = chinese self.english = english def _ repr__ (self): return "" .format (self.name, self.math, self.chinese, self.english)

Everything seems reasonable.

> std1 = Student ('Xiaoming', 76, 87, 68) > std1

But the program is not as intelligent as people, and will not automatically judge the legitimacy of the data according to the use of the scene. If the teacher accidentally enters the score and records it as a negative number, or more than 100, the program is imperceptible.

Smart, you immediately added judgment logic to the code.

Class Student: def _ _ init__ (self, name, math, chinese, english): self.name = name if 0 > > std.chinese call _ _ getattribute__ 99

After talking about data descriptors and non-data descriptors, we also need to understand the search rules of object attributes.

When we access an instance property, Python looks in the order of. _ _ dict__, the parent class of obj.__dict__ → type (obj). _ dict__ → type (obj). If the target attribute is found and it is found to be a descriptor, Python calls the descriptor protocol to change the default control behavior.

3. How to implement property based on descriptor

As explained above, we already know how to define descriptors and how descriptors work.

What I want to say is that it is just one of the most common applications of the descriptor protocol. As you may not know, many of the underlying implementation mechanisms of Python features are based on the descriptor protocol, such as @ property, @ classmethod, @ staticmethod and super.

Let's talk about property first.

With the previous foundation, we know the basic usage of property. Here I get straight to the topic and simplify it from the examples in the first article.

Class Student: def _ _ init__ (self, name): self.name = name @ property def math (self): return self._math @ math.setter def math (self, value): if 0 > > s1.math = 90 in _ set__ > s1.math in _ get__ 90

For those of you who have difficulty in understanding the operation of property, please be sure to refer to the two instructions I wrote above. If you have any other questions, please add Wechat to discuss with me.

4. How to implement staticmethod based on descriptor

After talking about property, let's talk about the implementation principles of @ classmethod and @ staticmethod.

I have defined a class here that implements static methods in two ways.

Class Test: @ staticmethod def myfunc (): print ("hello") # is equivalent to class Test: def myfunc (): print ("hello") # key: this is the embodiment of the descriptor myfunc = staticmethod (myfunc)

These two writing methods are equivalent, just like in property, in fact, the following two writing methods are also equivalent.

@ TestProperty def math (self): return self._math math = TestProperty (fget=math)

Let's turn to staticmethod.

From the comments above, you can see that staticmethod is actually equivalent to a descriptor class, and myfunc becomes a descriptor at this point. About the implementation of staticmethod, you can refer to the following code written by myself to understand it.

By calling this method, you can see that every time it is called, it passes through the _ _ get__ of the descriptor class.

> Test.myfunc () in staticmethod _ _ get__ hello > Test () .myfunc () in staticmethod _ _ get__ hello

5. How to implement classmethod based on descriptor

The same goes for the same classmethod.

Class classmethod (object): def _ init__ (self, f): self.f = f def _ get__ (self, instance, owner=None): print ("in classmethod _ get__") def newfunc (* args): return self.f (owner) * args) return newfunc class Test: def myfunc (cls): print ("hello") # key: this is the embodiment of the descriptor myfunc = classmethod (myfunc)

The verification results are as follows

> Test.myfunc () in classmethod _ _ get__ hello > Test () .myfunc () in classmethod _ _ get__ hello

Finished talking about the relationship between property, staticmethod, classmethod and descriptors. I think you should have a better understanding of the use of descriptors in Python. For the implementation principle of super, it is up to you to complete it yourself.

6. All instances share descriptors

Through the study of the above, do you think you already know enough about descriptors?

But here, I would like to say that there is something wrong with the above descriptor code.

What is the problem? Take a look at the following example.

Class Score: def _ init__ (self, default=0): self._value = default def _ get__ (self, instance, owner): return self._value def _ set__ (self, instance) Value): if 0 > > std1 = Student () > > std1 > > std1.math = 85 > > std1 > std2 = Student () > std2 # std2 actually shares the attribute value of std1 > std2.math = 100,100 > std1 # std2 will also change the attribute value of std1.

As a result, std2 actually shares the property value of std1, and as long as the variable of one instance changes, so does the variable of the other instance.

The root cause is that all three math,chinese,english are class variables at this time, which causes std2 and std1 to access class variables when they access the three variables math,chinese,english.

Is the question coming? How can the scores of Xiao Ming and Xiao Qiang be bound? This is obviously not in line with the actual business.

The use of descriptors creates convenience for us, but virtually brings us trouble. is this also a characteristic of descriptors?

Descriptors are a useful feature, and this problem occurs because the descriptor code we wrote before is wrong.

The descriptor mechanism, in my opinion, only preempts the order of visits, while the specific logic has to be tailored to local conditions, depending on the situation.

If you want to turn the three variables math,chinese,english into properties isolated from each other between instances, you should write like this.

Class Score: def _ init__ (self, subject): self.name = subject def _ get__ (self, instance, owner): return instance.__dict__ [self.name] def _ set__ (self, instance, value): if 0

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report