This article will try to introduce some tips that I use on a regular basis that I haven’t covered in other articles. Let’s find out!

Collating string input

The problem of collating user input is very common in programming. Usually, converting characters to lowercase or uppercase is enough, and sometimes you can use the regular expression module “Regex” to do this. But if the problem is complex, there may be a better way to solve it:

user_input = "This string has some whitespaces... "  
character_map = {  
    ord: (),ord: (),ord() :None  
}  
user_input.translate(character_map)  # This string has some whitespaces...
Copy the code

In this case, you can see that the Spaces “n” and “t” have been replaced with single Spaces, and the “r” has been deleted. This is just a simple example, we can go further, use “unicodeData” package to generate a large remapping table, and use “Combining ()” in it to generate and map, we can

Iterator Slice

Slicing an iterator returns a “TypeError” indicating that the generator object has no subscript, but we can solve this problem with a simple solution:

import itertools  
s = itertools.islice(range(50), 10.20)  # < itertools.islice object at 0x7f70fab88138>
for val in s:  
    ...
Copy the code

We can use “itertools.islice” to create an “islice” object, which is an iterator that produces the items we want. Note, however, that this operation uses all of the generator items before slicing, as well as all of the items in the “islice” object.

Skip the beginning of an iterable

Sometimes you deal with files that start with unwanted lines, such as comments. Again, “Itertools” provides a simple solution:

string_from_file = """ // Author: ... // License: ... // // Date: ... Actual content... "" " 
import itertools  
for line in itertools.dropwhile(lambda line: line.startswith("/ /"), string_from_file.split("")) :print(line)
Copy the code

This code only prints after the initial comment section. This approach is useful if we just want to discard the beginning of the iterable (the comment line that begins in this example) without knowing how long it should be.

Functions that contain only keyword arguments (kwargs)

It is helpful to create functions that take only keyword arguments as input to provide clearer function definitions when we use the following functions:

def test(*, a, b):  
    pass  
test("value for a", "value for b")  # TypeError: test() takes 0 positional arguments...  
test(a="value", b="value 2")  # Works...
Copy the code

As you can see, prefixing the keyword argument with a “” solves this problem. If we place certain parameters before “” parameters, they are obviously positional parameters.

Create objects that support the “with” statement

For example, we all know how to use the “with” statement to open a file or acquire a lock, but can we implement our own context expressions? Yes, we can use “Enter” and “exit” to implement the context management protocol:

class Connection:  
    def __init__(self) :.def __enter__(self) :  
        # Initialize connection...
    def __exit__(self, type, value, traceback) :  
        # Close connection...
with Connection() as c:  
    # __enter__() executes.# conn.__exit__() executes
Copy the code

This is the most common way to implement context management in Python, but there are simpler ways:

from contextlib import contextmanager  
@contextmanager  
def tag(name):  
    print(f"<{name}>")  
    yield  
    print(f"</{name}>")  
with tag("h1"):  
    print("This is Title.")
Copy the code

The above code implements the content management protocol using the ContextManager’s Manager decorator. The first part of the tag function (before yield) is executed when the with block is entered, then the with block is executed, and finally the rest of the tag function is executed.

With”slots“Save memory

If you’ve ever written a program that created a large number of instances of a class, you’ve probably noticed that your program suddenly needs a lot of memory. That’s because Python uses dictionaries to represent attributes of class instances, which makes it fast but not very memory efficient. Usually, this is not a serious problem. However, if your application is seriously affected by this, try slots:

class Person:  
    __slots__ = ["first_name"."last_name"."phone"]  
    def __init__(self, first_name, last_name, phone) :  
        self.first_name = first_name  
        self.last_name = last_name  
        self.phone = phone
Copy the code

When we defined the “slots” attribute, Python used small fixed-size arrays instead of dictionaries to represent the attributes, which greatly reduced the memory required for each instance. There are some disadvantages to using slots: we can’t declare any new attributes, we can only use existing attributes on slots. Also, classes with slots cannot use multiple inheritance.

Limit CPU and memory usage

If you don’t want to optimize your program’s memory or CPU usage, but want to limit it directly to a certain number, Python also has a library that can do this:

import signal import resource import os # To Limit CPU time def time_exceeded(signo, frame): print("CPU exceeded..." ) raise SystemExit(1) def set_max_runtime(seconds): # Install the signal handler and set a resource limit soft, hard = resource.getrlimit(resource.RLIMIT_CPU) resource.setrlimit(resource.RLIMIT_CPU, (seconds, hard)) signal.signal(signal.SIGXCPU, time_exceeded) # To limit memory usage def set_max_memory(size): soft, hard = resource.getrlimit(resource.RLIMIT_AS) resource.setrlimit(resource.RLIMIT_AS, (size, hard))Copy the code

As you can see in the code snippet above, there are options to set both the maximum CPU run time and the maximum memory usage limit. When limiting the CPU’s running time, we first get the soft and hard limits for that particular resource (RLIMIT_CPU), and then set it with the number of seconds specified by the parameter and the previously retrieved hard limits. Finally, if the CPU’s running time exceeds the limit, we signal the system to exit. In terms of memory usage, we retrieve both soft and hard limits again, and set it with “setrLimit” with the “size” parameter and the previously retrieved hard limit.

What can/can’t controls import

Some languages have very obvious mechanisms for exporting members (variables, methods, interfaces), such as Golang where only members that begin with a capital letter are exported. However, in Python, all members are exported (unless we use “all”) :

def foo():  
    pass  
def bar():  
    pass  
__all__ = ["bar"]
Copy the code

In the above code, we know that only the “bar” function is exported. Also, we can leave “all” empty so that nothing is exported, and when imported from this module, an “AttributeError” is made.

A simple way to implement comparison operators

Implementing all the comparison operators (such as lt, LE, gt, GE) for a class is tedious. Is there an easier way to do this? Functools. total_ordering is a good way to do this:

from functools import total_ordering  
@total_ordering  
class Number:  
    def __init__(self, value):  
        self.value = value  
    def __lt__(self, other):  
        return self.value < other.value  
    def __eq__(self, other):  
        return self.value == other.value  
print(Number(20) > Number(3))  
print(Number(1) < Number(5))  
print(Number(15) >= Number(15))  
print(Number(10) <= Number(2))
Copy the code

How exactly does this work? We use the “total_ordering” decorator to simplify the process of ordering class instances. We only need to define “lt” and “eq”, which are the smallest set of operations needed to implement the rest of the operations (and here decorators are also used to fill in the blanks for us).

conclusion

Not all of the features mentioned in this article are necessary or useful in everyday Python programming, but some of them may come in handy from time to time, and they may simplify tasks that are already lengthy and annoying. It should also be noted that all of these features are part of the Python standard library. It seems to me that some of these features don’t look like the standard ones included in the standard library, so when you implement some of the features mentioned in this article in Python, consult the Python standard library first. If you can’t find what you want, it’s probably just because you haven’t looked hard enough (if you haven’t, It must also exist in some third-party library).


At the end of this article is the most comprehensive Python collection ever (updated in a long time). The children next door are greedy to cry — click to receive