Maison  >  Article  >  développement back-end  >  Programmation Python avancée, huit compétences couramment utilisées !

Programmation Python avancée, huit compétences couramment utilisées !

WBOY
WBOYavant
2023-04-18 09:34:02949parcourir

Programmation Python avancée, huit compétences couramment utilisées !

Organisation de la saisie de chaîne

Le problème de l'organisation de la saisie utilisateur est extrêmement courant dans le processus de programmation. Souvent, il suffit de convertir les caractères en minuscules ou en majuscules, et parfois vous pouvez utiliser le module d'expression régulière « Regex » pour faire le travail. Mais si le problème est complexe, il existe peut-être une meilleure façon de le résoudre :

user_input = "Thisnstring hastsome whitespaces...rn"
character_map = {
ord('n') : ' ',
ord('t') : ' ',
ord('r') : None
}

user_input.translate(character_map)# This string has some whitespaces...

Dans cet exemple, vous pouvez voir que les caractères espace "n" et "t" ont été remplacés par un seul espace, et le "r " a été supprimé. Ceci n'est qu'un exemple très simple. Nous pouvons aller plus loin et utiliser le package "unicodedata" pour générer une grande table de remappage, et y utiliser "combining()" pour générer et mapper. Nous pouvons

Iterator Slice

Si vous le souhaitez. effectuez une opération de découpage sur l'itérateur, une "TypeError" sera renvoyée, indiquant que l'objet générateur n'a pas d'indice, mais nous pouvons utiliser une solution simple pour résoudre ce problème :

import itertools
s = itertools.islice(range(50), 10, 20)# <itertools.islice object at 0x7f70fab88138>
for val in s:
...

Nous pouvons utiliser "itertools.islice" pour créer one L'objet "islice" est un itérateur qui produit les éléments souhaités. Il faut cependant noter que cette opération utilise tous les éléments du générateur avant la tranche, ainsi que tous les éléments de l'objet "islice".

Ignorer le début des objets itérables

Parfois, vous devez gérer certains fichiers qui commencent par des lignes indésirables (comme les commentaires). "itertools" propose encore une fois une solution simple :

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

Ce code n'imprime le contenu qu'après la partie commentaire initiale. Cette méthode est utile si nous voulons uniquement supprimer le début de l'objet itérable (dans ce cas, la ligne de commentaire de début), mais nous ne savons pas combien de temps nous voulons que cette partie dure.

Fonction contenant uniquement des arguments de mots-clés (kwargs)

Lorsque nous utilisons la fonction suivante, il peut être utile de créer une fonction qui ne nécessite que des arguments de mots-clés en entrée pour fournir une définition de fonction plus claire :

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...

Like you Comme vous pouvez le voir , l'ajout d'un "*" avant le paramètre mot-clé peut résoudre ce problème. Si on met quelques paramètres avant le paramètre "*", ce sont évidemment des paramètres de position.

Créez des objets prenant en charge l'instruction "with"

Par exemple, nous savons tous comment utiliser l'instruction "with" pour ouvrir un fichier ou acquérir un verrou, mais pouvons-nous implémenter nos propres expressions contextuelles ? Oui, nous pouvons utiliser "__enter__" et "__exit__" pour implémenter le protocole de gestion de contexte :

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

C'est la manière la plus courante d'implémenter la gestion de contexte en Python, mais il existe un moyen plus simple :

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

Le paragraphe ci-dessus Le code implémente le protocole de gestion de contenu à l'aide du gestionnaire décorateur de contextmanager. La première partie de la fonction tag (la partie avant le rendement) a été exécutée lorsque le bloc with est entré, puis le bloc with est exécuté, et enfin le reste de la fonction tag est exécuté.

Économisez de la mémoire avec "__slots__"

Si vous avez déjà écrit un programme qui crée un grand nombre d'instances d'une certaine classe, vous avez peut-être remarqué que votre programme nécessite soudainement beaucoup de mémoire. En effet, Python utilise des dictionnaires pour représenter les attributs des instances de classe, ce qui le rend rapide, mais peu efficace en termes de mémoire. Normalement, ce n'est pas un problème grave. Cependant, si votre programme est sérieusement affecté par cela, vous pouvez aussi bien essayer "__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

Lorsque nous définissons l'attribut "__slots__", Python n'utilise pas de dictionnaire pour représenter l'attribut, mais utilise un petit fichier de taille fixe. tableau. Cela réduit considérablement la mémoire requise par instance. Utiliser "__slots__" présente également quelques inconvénients : nous ne pouvons déclarer aucun nouvel attribut, nous ne pouvons utiliser que les attributs existants sur "__slots__". De plus, les classes avec "__slots__" ne peuvent pas utiliser l'héritage multiple.

Limiter le "CPU" et l'utilisation de la mémoire

Si vous ne souhaitez pas optimiser l'utilisation de la mémoire ou du CPU par le programme, mais que vous souhaitez la limiter directement à un certain nombre, Python dispose également d'une bibliothèque correspondante qui peut le faire :

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))

Nous pouvons voir que dans l'extrait de code ci-dessus, il existe des options pour définir à la fois la durée d'exécution maximale du processeur et la limite maximale d'utilisation de la mémoire. Lors de la limitation du temps d'exécution d'un processeur, nous obtenons d'abord les limites souples et strictes pour cette ressource particulière (RLIMIT_CPU), puis nous les définissons en utilisant le nombre de secondes spécifié via les paramètres et la limite matérielle précédemment récupérée. Enfin, si le CPU dépasse la limite, nous signalons au système de quitter. En termes d'utilisation de la mémoire, nous récupérons à nouveau les limites souples et strictes et les définissons en utilisant "setrlimit" avec le paramètre "size" et la limite stricte précédemment récupérée.

Contrôler ce qui peut/ne peut pas être importé

Certaines langues ont un mécanisme très évident pour exporter les membres (variables, méthodes, interfaces). Par exemple, dans Golang, seuls les membres commençant par une majuscule sont exportés. Cependant, en Python, tous les membres sont exportés (sauf si on utilise "__all__") :

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

Dans le code ci-dessus, on sait que seule la fonction "bar" est exportée. De même, nous pouvons laisser "__all__" vide pour que rien ne soit exporté, ce qui provoquera une "AttributeError" lors de l'importation depuis ce module.

实现比较运算符的简单方法

为一个类实现所有的比较运算符(如 __lt__ , __le__ , __gt__ , __ge__)是很繁琐的。有更简单的方法可以做到这一点吗?这种时候,「functools.total_ordering」就是一个很好的帮手:

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))

这里的工作原理究竟是怎样的呢?我们用「total_ordering」装饰器简化实现对类实例排序的过程。我们只需要定义「__lt__」和「__eq__」就可以了,它们是实现其余操作所需要的最小的操作集合(这里也体现了装饰器的作用——为我们填补空白)。

结语

并非本文中所有提到的功能在日常的 Python 编程中都是必需或有用的,但是其中某些功能可能会不时派上用场,而且它们也可能简化一些原本就很冗长且令人烦恼的任务。还需指出的是,所有这些功能都是 Python 标准库的一部分。而在我看来,其中一些功能似乎并不像标准库中包含的标准内容,所以当你使用 Python 实现本文提到的某些功能时,请先参阅 Python 的标准库,如果你不能找到想要的功能,可能只是因为你还没有尽力查找(如果真的没有,那它肯定也存在于一些第三方库)。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer