Cette spécification est rédigée comme suit:PEP8Base,Référence HuaweiPythonSpécifications générales de codage、Spécification de programmation de sécurité,Et combiné avec le Consensus de l'industrie,ParticipationMindSporeLe développement communautaire doit d'abord être conforme au contenu de cette spécification.(AvecPEP8Débat consacré aux conflits),Suivi des autres recommandationsPEP8Spécifications.
En cas d'objection à la règle,Présentation des recommandationsissueJustification,MéridienMindSporeLes modifications entrent en vigueur après l'acceptation de l'examen par l'équipe des opérations communautaires..
a
MindSporeOpen Source Community
Les règles 1.1.1 Nom du paquet,Nom du module:Minuscule,Pas de soulignement.
Les règles 1.1.2 Nom de la classe:Utiliser le format Hump,Majuscules initiales,Préfixe de soulignement de classe privée.
class _Foo:
_instance = None
pass
Les règles 1.1.3 Nom de la fonction、Nom de la variable:Minuscule,Segmentation des soulignements de mots multiples.
def _func_example(path):
pass
Suggestion 1.1.4 À l'exception des itérateurs et des compteurs,Interdire les noms à un seul caractère.
Les règles 1.2.1 Ne pas dépasser le nombre de caractères par ligne 120 - Oui..
Si plus de120Caractères,Veuillez choisir un moyen raisonnable d'envelopper la ligne.
Les règles 1.2.2 Indenter avec des espaces,Chaque indentation4Espaces,InterdictiontabIndentation.
Les règles 1.2.3 importOrdre:Bibliothèque standard、Tiers、Modules personnalisés.
Les règles 1.2.4 Les parenthèses ne sont pas utilisées dans les déclarations de retour et les déclarations conditionnelles .
Les règles 1.2.5 Double ligne vide entre la fonction au niveau du module et la classe , Une ligne vide entre les fonctions des membres de la classe , Ajouter des lignes vides au besoin entre le commentaire et le Code , Pas plus de deux lignes vides en principe .
Les règles 1.2.6 Suppression directe de codes invalides ou redondants , Ne pas commenter 、TODO Etc. reste dans le Code ,SuggestionissueEnregistrement.
Les règles 1.3.1 Le commentaire de l'en - tête du fichier doit contenir un avis de droit d'auteur .
Tous lespythonDocumentation, Doit contenir la Déclaration de droit d'auteur suivante :
# Copyright 2019 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
""" Add notes. """
import xxx
À propos de copyright Notes ,Attention!:
2020 Nouveaux fichiers créés en ,Je crois.Copyright 2020 Huawei Technologies Co., Ltd
2019 Année de création ,2020 Année de la modification ,Je crois.Copyright 2019-2020 Huawei Technologies Co., Ltd
Les règles 1.3.2 Classe externe 、Méthodes、Opérateur、CellFormat des notes.
class
Et def
Le format des commentaires est le même pour , Adopter des pythonSyntaxe annotée, Écrivez sous la Déclaration et indentez ,Tous les class
Et def
Des commentaires sont nécessaires , Les classes et les méthodes à l'intérieur du module peuvent écrire une seule introduction .Les règles 1.3.3 Le masquage par annotation n'est pas autorisé pylintAlarmes.
Les règles 1.4.1 Journal des exceptions texte en majuscules .
Les règles 1.4.2 Le nom de la variable dans le texte du journal doit être indiqué en guillemets simples .
Les règles 2.1.1 Interface utilisateur dans le fichier __all__Description,__all__Placé dansimport Entre et Code .
Les règles 2.1.2 Les noms de méthodes non externes utilisés dans le fichier courant sont préfixés par des soulignements , La méthode utilisée par l'Inter - module interne n'a pas besoin d'un préfixe de soulignement , Interface utilisateur à __all__Déclaration du milieu.
Les règles 2.2.1 Vérification de la légalité de toutes les données externes ,Y compris, sans s'y limiter:Paramètres d'entrée de la fonction、 Ligne nommée d'entrée externe 、Format du fichier,Taille du fichier、Variables d'environnement、Données des utilisateurs, etc..
Suggestion 2.2.2 Le chemin du fichier doit être normalisé avant utilisation .
Lorsque le chemin du fichier provient de données externes , Le chemin du fichier doit d'abord être normalisé , S'il n'y a pas de normalisation , Un attaquant a la possibilité d'accéder à un fichier par un chemin de fichier de construction malveillant :
Par exemple,Un attaquant peut construire“…/…/…/etc/passwd” Pour accéder à n'importe quel fichier .
InlinuxEn bas.,UtiliserrealpathFonctions,InwindowsEn bas.,UtiliserPathCanonicalize La fonction normalise le chemin du fichier .
Les règles 2.2.3 Interdire les appelsOS L'analyseur de commandes exécute des commandes ou exécute des programmes .
Utiliser des entrées non vérifiées et non fiables comme paramètre ou partie d'une commande système , Peut provoquer une vulnérabilité d'injection de commande . Pour les vulnérabilités d'injection de commandes , La commande sera exécutée avec Python L'application est exécutée au même niveau de privilège , Il fournit un système similaire à l'attaquant shellLa fonction de.InPythonMoyenne,os.system Ou os.popen Souvent utilisé pour invoquer un nouveau processus , Si la commande exécutée provient d'une entrée externe , Des commandes et des injections de paramètres peuvent être générées .
Quand vous exécutez un ordre,Veuillez noter ce qui suit:
【Exemple de code d'erreur1】
Un attaquant peut trouver une variable d'environnement APPHOMELa valeur correspondante, Et placer les constantes dans le répertoire approprié INITCMD Le Programme d'attaque correspondant , Atteindre l'effet de l'exécution :
home = os.getenv('APPHOME')
cmd = os.path.join(home, INITCMD)
os.system(cmd)
【Exemple de code d'erreur2】
Aucune propriété de contrôle backuptype Valeur de, Ceci est entré par l'utilisateur , Un attaquant pourrait attaquer ,
Par exemple:L'entrée de l'utilisateur est:" && del c:\dbms\. ":
# Les valeurs proviennent de la configuration de l'utilisateur
btype = req.field('backuptype')
cmd = "cmd.exe /K \"c:\\util\\rmanDB.bat " + btype + "&&c:\\util\\cleanup.bat\""
os.system(cmd)
【Exemple de code d'erreur3】
Aucune propriété de contrôle backuptype Valeur de, Ceci est entré par l'utilisateur , Un attaquant pourrait attaquer ,Par exemple:L'entrée de l'utilisateur est:" && del c:\dbms\. ":
import os
import sys
try:
print(os.system("ls " + sys.argv[1]))
except Exception as ex:
print('exception:', ex)
Un attaquant peut exploiter ce programme vulnérable en utilisant la commande suivante :
python test.py ". && echo bad"
Deux commandes seront effectivement exécutées :
ls .
echo bad
【Exemple de code correct】
Ne pas utiliser os.system,Vous pouvez utiliser la norme API Remplacer les commandes du système d'exécution pour accomplir la tâche :
import os
import sys
try:
print(os.listdir(sys.argv[1]))
except Exception as ex:
print(ex)
Les règles 2.3.1 L'exception doit être traitée correctement , Inhiber ou ignorer les exceptions vérifiées .
Chaqueexcept Tous les blocs doivent s'assurer que le programme ne continue à fonctionner que s'il continue à fonctionner .except Le bloc doit être récupéré de l'exception , Ou lancer à nouveau pour le moment catch Une autre exception au contexte du bloc pour permettre la couche externe la plus proche try-except Bloc d'instruction pour le travail de récupération .
【Exemple de code correct】
La bonne chose à faire est,Ne pas utiliser os.system,Vous pouvez utiliser la norme API Remplacer les commandes du système d'exécution pour accomplir la tâche :
validFlag = False
while not validFlag:
try:
# If requested file does not exist, throws FileNotFoundError
# If requested file exists, sets validFlag to true
validFlag = True
except FileNotFoundError:
import traceback
traceback.print_exc()
【Exceptions】:
Les règles 2.3.2 Utilisertry…except… Lorsque la structure protège le Code , Doit être utilisé après une exception finally… La structure garantit la libération de l'objet d'opération .
Utilisertry…except… Lorsque la structure protège le Code , Si une exception s'est produite dans l'exécution du Code , Pour pouvoir fermer l'objet d'opération de façon fiable ,À utiliserfinally… La structure assure la libération de l'objet d'opération .
【Exemple de code correct】
handle = open(r"/tmp/sample_data.txt") # May raise IOError
try:
data = handle.read() # May raise UnicodeDecodeError
except UnicodeDecodeError as decode_error:
print(decode_error)
finally:
handle.close() # Always run after try:
Les règles 2.3.3 Ne pas utiliser“except:” Déclaration pour saisir toutes les exceptions .
En ce qui concerne les anomalies, , Python Très tolérant. ,“except:” Les déclarations capturent vraiment les Python Toutes les erreurs, y compris les erreurs de syntaxe .Utiliser“except:” Il est facile de cacher le vrai bug,Nous utilisonstry…except… Lorsque la structure protège le Code , Les exceptions auxquelles on s'attend à ce qu'elles soient traitées devraient être claires .Exception La classe est la classe de base de la plupart des exceptions d'exécution , En général, il faut également éviter de exceptUtilisé dans l'énoncé.En général,try Seules les déclarations qui doivent traiter l'exception à l'emplacement actuel doivent être incluses ,except Ne capturez que les exceptions qui doivent être traitées . Par exemple, pour le Code qui ouvre le fichier ,try Ne devrait contenir que openDéclarations,exceptCapture seulementFileNotFoundErrorAnomalie. Pour d'autres exceptions inattendues , Laissez la fonction supérieure capturer , Ou passer à l'extérieur du programme pour exposer adéquatement le problème .
【Exemple de code d'erreur】
Le code suivant peut lancer deux exceptions ,Utiliser“except:” Lorsque les déclarations sont traitées uniformément ,Si ouiopenException à l'exécution,Sera“except:”Après la Déclarationhandle Appelé si invalide close,Erreur signaléehandleNon défini.
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
data = handle.read() # May raise UnicodeDecodeError
except:
handle.close()
【Exemple de code correct】
try:
handle = open(r"/tmp/sample_data.txt") # May raise IOError
try:
data = handle.read() # May raise UnicodeDecodeError
except UnicodeDecodeError as decode_error:
print(decode_error)
finally:
handle.close()
except(FileNotFoundError, IOError) as file_open_except:
print(file_open_except)
Les règles 2.3.4 Non.exceptDans la brancheraise Doit être anormal .
raise Les mots - clés utilisés seuls ne peuvent apparaître que dans try-exceptDans la Déclaration,Re - lancerexcept Anomalie saisie .
【Exemple de code d'erreur】
a = 1
if a == 1:
raise
【Exemple de code correct1】raiseUnExceptionOu personnaliséException
a = 1
if a == 1:
raise Exception
【Exemple de code correct2】Intry-exceptUtilisé dans l'énoncé
try:
f = open('myfile.txt')
s = f.readline()
i = int(s.strip())
except IOError as e:
print("I/O error({0}): {1}".format(e.errno, e.strerror))
except ValueError:
print("Could not convert data to an integer.")
except Exception:
print("Unexpected error:", sys.exc_info()[0])
raise
Les règles 2.4.1 pickleProblèmes de sécurité,Utilisation interditepickle.load、cPickle.loadEtshelve Le module charge des données non fiables .
Les règles 2.4.2 Utiliser des nombres aléatoires sûrs .
Python La fonction de génération de nombres aléatoires est randomMise en œuvre dans le module, Générateur de nombres pseudo - aléatoires avec différentes distributions . Le nombre aléatoire qui en résulte peut être réparti uniformément ,Distribution gaussienne,Distribution lognormale, Distribution exponentielle négative et alpha,betaRépartition, Mais ces nombres aléatoires sont pseudo - aléatoires , Ne peut pas être appliqué à des fins de chiffrement de sécurité .
Veuillez utiliser/dev/randomGénérer un nombre aléatoire sécurisé, Ou utilisé dans python 3.6 Version officiellement introduite secrets Le module génère un nombre aléatoire sécurisé .
【Exemple de code d'erreur】
import random
# Nombre pseudoaléatoire
func = random.SystemRandom()
print(func.random())
print(func.randint(0, 10))
【Exemple de code correct】
import platform
# Longueur voir la spécification de l'algorithme cryptographique , Différentes scènes nécessitent des longueurs différentes
randLength = 16
if platform.system() == 'Linux':
with open("/dev/random", 'rb') as file:
sr = file.read(randLength)
print(sr)
Les règles 2.4.3 assert Les déclarations ne sont généralement utilisées que dans le Code de test ,Interdit dansRelease Inclus dans la version assertFonction.
assert Ne doit être utilisé que pour les essais internes au cours de la recherche et du développement ,C'est parti.AssertionError Une exception indique une erreur de conception ou de codage du logiciel , Le logiciel doit être modifié pour résoudre . Interdire l'inclusion de assertFonction.