In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 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 "what are the Python programming code skills?". In the operation of actual cases, many people will encounter such a dilemma. Next, 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!
Python provides a unique set of tools and language features to make your code more elegant, readable, and intuitive. Choose the right tool for the right problem, and your code will be easier to maintain. In this article, we will examine three of these tools: magic methods, iterators and generators, and method magic.
Magic method
The magic method can be seen as a conduit for Python. They are called "underlying" methods and are used for some built-in methods, symbols, and operations. A common magic method that you may be familiar with is _ _ init__ (), which is called when we want to initialize a new instance of a class.
You may have seen other common magic methods, such as _ _ str__ and _ _ repr__. There is a whole set of magic methods in Python, and by implementing some of these methods, we can modify the behavior of an object and even make it behave like a built-in data type, such as a number, list, or dictionary.
Let's create a Money class as an example:
Class Money: currency_rates = {'$': 1, 'girls': 0.88,} def _ init__ (self, symbol, amount): self.symbol = symbol self.amount = amount def _ repr__ (self): return'% .2f'% (self.symbol, self.amount) def convert (self) Other): "Convert other amount to our currency" new_amount = (other.amount / self.currency_ rates [other.symbol] * self.currency_ rates [self.symbol]) return Money (self.symbol, new_amount)
This class definition defines a currency exchange rate for a given currency symbol and exchange rate, specifies an initializer (also known as a constructor), and implements _ _ repr__, so when we print this class, we will see a friendly representation, such as $2.00, which is an instance of Money ('$', 2.00) with a currency symbol and amount. Most importantly, it defines a method that allows you to convert between different currencies using different exchange rates.
Open Python shell and assume that we have defined the cost of food in two different currencies, as follows:
> soda_cost = Money ('$', 5.25) > soda_cost $5.25 > pizza_cost = Money ('$', 7.99) > pizza_cost = 7.99
We can use magic methods to make the instances of this class interact with each other. Suppose we want to be able to add two instances of this class together, even if they are in different currencies. To achieve this, we can implement the magic method _ _ add__ on the Money class:
Class Money: #... Previously defined methods... Def _ add__ (self, other): "Add 2 Money instances using'+'" new_amount = self.amount + self.convert (other). Amount return Money (self.symbol, new_amount)
Now we can use this class in a very intuitive way:
> soda_cost = Money ('$', 5.25) > pizza_cost = Money ('pizza_cost', 7.99) > soda_cost + pizza_cost $14.33 > pizza_cost + soda_cost $12.61
When we add the two instances together, we get the result represented by * currency symbols defined. All the transformations are done seamlessly at the bottom. If we want, we can also implement _ _ sub__, for subtraction, _ _ mul__ for multiplication, and so on. Read the Analog Digital Type or Magic method Guide for more information.
We learned that _ _ add__ maps to the built-in operator +. Other magic methods can be mapped to symbols like []. For example, getting an item in a dictionary through an index or key actually uses the _ _ getitem__ method:
> d = {'one': 1,' two': 2} > d ['two'] 2 > d.qualified getitemps _ (' two') 2
Some magic methods even map to built-in functions, such as _ _ len__ () to len ().
Class Alphabet: letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' def _ len__ (self): return len (self.letters) > my_alphabet = Alphabet () > len (my_alphabet) 26 Custom iterator
Custom iterators are a very powerful but confusing topic for new and experienced Python developers.
Many built-in types, such as lists, collections, and dictionaries, have implemented protocols that allow them to iterate at the underlying level. This allows us to traverse them easily.
> for food in ['Pizza',' Fries']: print (food +'. Yumqi') Pizza. Yum!Fries. Yum!
How do we iterate over our own custom classes? First of all, let's clarify some terminology.
To be an iterable object, a class needs to implement _ _ iter__ ()
The _ _ iter__ () method needs to return an iterator
To be an iterator, a class needs to implement _ _ next__ () (or next () in Python 2), and a StopIteration exception must be thrown when there are no more items to iterate over.
Whoo-hoo! It sounds complicated, but once you remember these basic concepts, you can iterate at any time.
When do we want to use custom iterators? Let's imagine a scenario where we have an instance of Server running different services, such as http and ssh, on different ports. Some of these services are in the active state, while others are in the inactive state.
Class Server: services = [{'active': False,' protocol': 'ftp',' port': 21}, {'active': True,' protocol': 'ssh',' port': 22}, {'active': True,' protocol': 'http',' port': 80},]
When we traverse the Server instance, we only want to traverse the services that are in active. Let's create an IterableServer class:
Class IterableServer: def _ _ init__ (self): self.current_pos = 0 def _ next__ (self): pass # TODO: implement and remember to throw StopIteration
First, we initialize the current position to 0. Then, we define a _ _ next__ () method to return the next item. We will also make sure that StopIteration is thrown when no more items are returned. So far so good! Now, let's implement this _ _ next__ () method.
Class IterableServer: def _ init__ (self): self.current_pos = 0. # We initialize the current location to 0 def _ _ iter__ (self): # We can return self here because _ _ next__ return self def _ _ next__ (self): while self.current_pos is implemented
< len(self.services): service = self.services[self.current_pos] self.current_pos += 1 if service['active']: return service['protocol'], service['port'] raise StopIteration next = __next__ # 可选的 Python2 兼容性 我们对列表中的服务进行遍历,而当前的位置小于服务的个数,但只有在服务处于活动状态时才返回。一旦我们遍历完服务,就会抛出一个 StopIteration 异常。 因为我们实现了 __next__() 方法,当它耗尽时,它会抛出 StopIteration。我们可以从 __iter__() 返回 self,因为 IterableServer 类遵循 iterable 协议。 现在我们可以遍历一个 IterableServer 实例,这将允许我们查看每个处于活动的服务,如下所示: >> > for protocol, port in IterableServer (): print ('service% s is running on port% d'% (protocol, port)) service ssh is running on port 22 service http is running on port 21
Great, but we can do better! In an example like this, our iterator does not need to maintain a lot of state, we can simplify the code and use generator (generator) instead.
Class Server: services = [{'active': False,' protocol': 'ftp',' port': 21}, {'active': True,' protocol': 'ssh',' port': 22}, {'active': True,' protocol': 'http',' port': 21} ] def _ _ iter__ (self): for service in self.services: if service ['active']: yield service [' protocol'], service ['port']
What exactly is the yield keyword? Use yield when defining generator functions. This is a bit like return, where return exits the function after returning a value, but yield pauses execution until the next time it is called. This allows the functionality of your generator to remain in state until it is restored. Check yield's documentation for more information. With the generator, we don't have to maintain the state manually by remembering our location. The generator only knows two things: what it needs to do now and what it needs to do for the next project. Once we reach the execution point, that is, yield is no longer called, we know to stop iterating.
This is because of some built-in Python magic. As we can see in the Python documentation on _ _ iter__ (), if _ _ iter__ () is implemented as a generator, it automatically returns an iterator object that provides the _ _ iter__ () and _ _ next__ () methods. Read this great article to learn more about iterators, iterable objects, and generators.
Method magic
Because of its unique aspects, Python offers some interesting ways of magic as part of the language.
One example is the alias feature. Because functions are just objects, we can assign them to multiple variables. For example:
> def foo (): return 'foo' > foo ()' foo' > bar = foo > bar () 'foo'
We'll see how it works later.
Python provides a convenient built-in function called getattr (), which takes object, name, and default parameters and returns the property name on object. This programming allows us to access instance variables and methods. For example:
> class Dog: sound = 'Bark' def speak (self): print (self.sound +'!', self.sound +'!) > > fido = Dog () > fido.sound'Bark' > getattr (fido, 'sound')' Bark' > > fido.speak > getattr (fido, 'speak') > > fido.speak () Bark! Bark! > speak_method = getattr (fido, 'speak') > speak_method () Bark! Bark!
This is a cool technique, but how do we use getattr in practice? Let's look at an example where we write a small command-line tool to process commands dynamically.
Class Operations: def say_hi (self, name): print ('Hello,', name) def say_bye (self, name): print (' Goodbye,', name) def default (self, arg): print ('This operation is not supported.') If _ _ name__ = ='_ main__': operations = Operations () # suppose we have done error handling command, argument = input ('>'). Split () func_to_call = getattr (operations, command, operations.default) func_to_call (argument)
The output of the script is:
$python getattr.py > say_hi NinaHello, Nina > blah blahThis operation is not supported.
Next, let's look at partial. For example, functool.partial (func, * args, * * kwargs) allows you to return a new partial object that behaves like func with parameters args and kwargs. If more args is passed in, they will be attached to the args. If more kwargs is passed in, they extend and overwrite the kwargs. Let's look at this with a short example:
> from functools import partial > basetwo = partial (int, base=2) > basetwo > basetwo ('10010') 18 # this is equivalent to > int ('10010, base=2)
Let's see how this method magic fits together in some sample code in one of my favorite libraries called agithub, a (low-named) REST API client with transparent syntax that allows you to quickly build any REST API prototype (not just GitHub) with minimal configuration. I find this project interesting because it is very powerful, but only about 400 lines of Python code. You can add support for any REST API in about 30 lines of configuration code. Agithub knows everything the protocol requires (REST, HTTP, TCP), but it doesn't consider the upstream API. Let's delve into its implementation.
Here's how we define a simplified version of the endpoint URL for GitHub API and any other related connection properties. Check out the complete code here.
Class GitHub (API): def _ init__ (self, token=None, * args, * * kwargs): props = ConnectionProperties (api_url = kwargs.pop ('api_url',' api.github.com')) self.setClient (Client (* args, * * kwargs) self.setConnectionProperties (props))
Then, once the access token is configured, you can start using GitHub API.
> gh = GitHub ('token') > status, data = gh.user.repos.get (visibility='public', sort='created') > # ^ Mapping to GET / user/repos > data... ['tweeter',' snipey', '...]
Please note that you need to make sure that the URL is spelled correctly because we did not verify the URL. If URL does not exist or any other errors occur, the error thrown by API is returned. So how does all this work? Let's find out. First, we will look at a simplified example of the API class:
Class API: #... Other methods... Def _ _ getattr__ (self, key): return IncompleteRequest (self.client). _ _ getattr__ (key) _ getitem__ = _ _ getattr__
Each call on the API class calls the IncompleteRequest class as the specified key.
Class IncompleteRequest: #... Other methods... Def _ getattr__ (self, key): if key in self.client.http_methods: htmlMethod = getattr (self.client, key) return partial (htmlMethod, url=self.url) else: self.url + ='/'+ str (key) return self _ getitem__ = _ getattr__ class Client: http_methods = ('get') # and post, put, patch and so on. Def get (self, url, headers= {}, * * params): return self.request ('GET', url, None, headers)
If * one call is not a HTTP method (such as get, post, etc.), IncompleteRequest with an additional path is returned. Otherwise, it gets the correct function corresponding to the HTTP method from the Client class and returns partial.
What happens if we give a path that doesn't exist?
> status, data = this.path.doesnt.exist.get () > status... four hundred and four
Because the _ _ getattr__ alias is _ _ getitem__:
> owner, repo = 'nnja',' tweeter' > status, data = gh.repos [owner] [repo] .pulls.get () > > # ^ Maps to GET / repos/nnja/tweeter/pulls > data.... # {.} "what are the skills of Python programming code"? thank you for your reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
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.