In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains the "Python immutable data structure example analysis", the content of the article is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "Python immutable data structure example analysis"!
Let's start by thinking about squares and rectangles. If we put aside the implementation details and consider only from the perspective of the interface, is the square a subclass of the rectangle?
The definition of subclasses is based on the Richter substitution principle. A subclass must be able to do what the superclass does.
How to define an interface for a rectangle?
From zope.interface import Interface class IRectangle (Interface): def get_length (self): "Square can do it"def get_width (self):" Square can do it "def set_dimensions (self, length, width):" Ah oh "
If we define it this way, the square cannot be a subclass of the rectangle: if the length and width are not equal, it cannot respond to the set_dimensions method.
Another way is to choose to make the rectangle immutable.
Class IRectangle (Interface): def get_length (self): "Square can do it"def get_width (self):" Square can do it "def with_dimensions (self, length, width):" return a new rectangle ""
Now we can think of a square as a rectangle. When calling with_dimensions, it can return a new rectangle (it is not necessarily a square), but it itself has not changed, it is still a square.
This seems like an academic problem-until we think that squares and rectangles can be seen as the sides of a container in a sense. After understanding this example, we will deal with more traditional containers to solve more realistic cases. For example, consider a random access array.
We now have ISquare and IRectangle, and ISequere is a subclass of IRectangle.
We want to put the rectangle in the random access array:
Class IArrayOfRectangles (Interface): def get_element (self, I): "returns a rectangle"def set_element (self, I, rectangle):" 'rectangle' can be any IRectangle object "
We also want to put the square in the random access array:
Class IArrayOfSquare (Interface): def get_element (self, I): "returns a square"def set_element (self, I, square):" 'square' can be any ISquare object "
Although ISquare is a subset of IRectangle, no array can implement both IArrayOfSquare and IArrayOfRectangle.
Why not? Suppose bucket implements the functionality of these two classes.
> rectangle = make_rectangle (3,4) > bucket.set_element (0, rectangle) # this is a legal operation in IArrayOfRectangle > thing = bucket.get_element (0) # IArrayOfSquare requires that the thing must be a square > assert thing.height = = thing.widthTraceback (most recent call last): File ", line 1, in AssertionError
The inability to implement both types of functionality at the same time means that the two classes cannot form an inheritance relationship, even if ISquare is a subclass of IRectangle. The problem comes from the set_element method: if we implement a read-only array, then IArrayOfSquare can be a subclass of IArrayOfRectangle.
In both mutable IRectangle and mutable IArrayOf* interfaces, variability makes it more difficult to think about types and subclasses-giving up the ability to transform means that the relationship between types that our intuition wants can be established.
Variability can also have a scope impact. This problem occurs when a shared object is changed by code in two places. A classic example is when two threads change a shared variable at the same time. However, in a single-threaded program, it is simple to share a variable even in two places far apart. From the perspective of the Python language, most objects can be accessed from many locations: for example, in module global variables, or in a stack trace, or as class properties.
If we can't constrain sharing, then we might want to consider constraining variability.
This is an immutable rectangle that takes advantage of the attr library:
Attr.s (frozen=True) class Rectange (object): length = attr.ib () width = attr.ib () @ classmethod def with_dimensions (cls, length, width): return cls (length, width)
This is a square:
Attr.s (frozen=True) class Square (object): side = attr.ib () @ classmethod def with_dimensions (cls, length, width): return Rectangle (length, width)
Using the frozen parameter, we can easily make classes created by attrs immutable. The work of correctly implementing the _ _ setitem__ method is left to someone else and is invisible to us.
It's still easy to modify an object; but we can't change its nature.
Too_long = Rectangle (100,4) reasonable = attr.evolve (too_long, length=10)
Pyrsistent allows us to have immutable containers.
# Vector consisting of integers a = pyrsistent.v (1,2,3) # Vector b = a.set (1, "hello") that is not made up of integers
Although b is not a vector made up of integers, nothing can change the property that an is made up of integers only.
What if a has a million elements? Will b copy 999999 of these elements? Pyrsistent has "big O" performance guarantee: the time complexity of all operations is O (log n). It also comes with an optional C language extension to improve on "Big O" performance.
When modifying nested objects, the concept of "converter" is involved:
Blog = pyrsistent.m (title= "My blog", links=pyrsistent.v ("github", "twitter"), posts=pyrsistent.v (pyrsistent.m (title= "no updates", content= "Ihumm busy"), pyrsistent.m (title= "still no updates", content= "still busy")) new_blog = blog.transform (["posts", 1, "content"] "pretty busy")
New_blog will now be the immutable equivalent of the following:
{'links': [' github', 'twitter'],' posts': [{'content':' Isimm busy', 'title':' no updates'}, {'content':' pretty busy', 'title':' still no updates'}], 'title':' My blog'}
But blog remains the same. This means that anyone who has a reference to an old object is not affected: the transformation will only have a local effect.
This is useful when sharing is rampant. For example, the default parameters for a function:
Def silly_sum (a, b, extra=v (1,2)): extra= extra.extend ([a, b]) return sum (extra) Thank you for your reading. The above is the content of "example Analysis of Python immutable data structure". After the study of this article, I believe you have a deeper understanding of the problem of Python immutable data structure example analysis, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.