TL; DR
Pour:
- pythonEtjavascriptDeruntime(En gros, c'estcpython[Non, pas du tout.cython!]EtNode.js)Tout est prêt.
- Le langage auxiliaire utilise des paquets complexes(Par exemplepythonÇa marche.numpy、javascriptAvec un peu deNode.jsDeC++Extension, etc.)
- Si nécessaire pour l'efficacité opérationnelle:
- pythonAvecjavascriptIl n'y a pas beaucoup d'interaction entre,L'objet transmis n'est pas trop grand、C'est trop compliqué.,De préférence tous les objets sérialisables
- javascriptLa proportion n'est pas si faible.Sinon,pythonTunejsEt si,DémarrageNode.jsLe Sous - processus est plus lent que le programme réel;jsTunepythonEt si,Parce quejsVite!,Il faut beaucoup de temps pour attendrepythonAllez..
- Parce queIPCLe taux approximatif synchronisera l'entrée et la sortie avec le thread,Moins de langue principale, plus de processus、Programmation simultanée comme thread
Il y a une bibliothèque.!Il y a une bibliothèque.!Il y a une bibliothèque.!
pythonTunejavascript
- JSPyBridge:
pip install javascript
- Avantages:
- L'auteur maintient toujours ,Retourissue Et les mises à jour sont assez rapides .
- Prise en charge des pythonEtnodeVersion,Facile à installer
- Support de base pour les appels mutuels , Y compris les fonctions de liaison ou de rappel .
- Inconvénients: Absence de mécanisme de destruction raisonnable ,
import javascript
Est considéré comme une connexion JSFin, Tous les Threads multithreads à utiliser sont initialisés .Sipython Le programme principal veut redémarrer la paire JSConnexion à, Ou le programme principal utilise plusieurs processus , Je veux me connecter une fois par processus JS,C'est difficile à faire., Il est facile de faire des erreurs .
- Avantages:
- PyExecJS:
pip install PyExecJS
, Les anciens articles techniques poussent ce paquet- Avantages: Soutien saufNode.jsAutresruntime,Par exemplePhantomJSQuelque chose comme ça.
- Inconvénients: End of Life, L'auteur a arrêté la maintenance
javascriptTunepython
( Parce que ça ne correspond pas vraiment à mes besoins de projet , Donc je ne sais pas grand - chose )
- JSPyBridge:
npm i pythonia
- node-python-bridge:
npm install python-bridge
- python-shell:
npm install python-shell
Principes
Tout d'abord,, La méthode repose sur la prémisse que les deux langues ont été installées runtime, Et peut être appelé par la ligne de commande runtime Exécuter un fichier ou un script de chaîne de caractères .Par exemple,Chargez.cpython Après ça, on pourra passer par python a.py
Pour courirpythonProcédure,Chargez.Node.jsAprès ça, on pourra passer parnode a.js
Ounode -e "some script"
Attends de courir JSProcédure.
Bien sûr.,Dans le cas le plus simple, Si nous n'avons besoin d'appeler qu'une seule langue secondaire , Et il n'y a pas d'interaction ( Ou une seule interaction au plus ), Alors trouvez un appel de méthode. CLIJusteOKC'est. Pour l'entrée dans la langue secondaire stdin Ou passer un paramètre en ligne de commande , Lire la sortie de la commande comme sortie du sous - langage .
Par exemple,pythonÇa marchesubprocess.Popen
,subprocess.call
,subprocess.check_output
Ouos.system
Quelque chose comme ça.,Node.jsÇa marchechild_process
La méthode de Li,exec
Oufork
Quelque chose comme ça..Il est important de noter que, Si d'autres paquets doivent être référencés ,Node.jsIl convient de noter quenode_modules
Exécuter les instructions dans le répertoire où elles se trouvent ,python Attention au réglage PYTHONPATHVariables d'environnement.
# Need to set the working directory to the directory where `node_modules` resides if necessary
>>> import subprocess
>>> a, b = 1, 2
>>> print(subprocess.check_output(["node", "-e", f"console.log({a}+{b})"]))
b'3\n'
>>> print(subprocess.check_output(["node", "-e", f"console.log({a}+{b})"]).decode('utf-8'))
3
// Need to set PYTHONPATH in advance if necessary
const a = 1;
const b = 2;
const { execSync } = require("child_process");
console.log(execSync(`python -c "print(${a}+${b})"`));
//<Buffer 33 0a>
console.log(execSync(`python -c "print(${a}+${b})"`).toString());
//3
//
S'il y a des interactions complexes , Pour passer des objets complexes , Certains peuvent être sérialisés , Certains ne peuvent pas être sérialisés du tout ,Et alors??
Il s'agit essentiellement d'utiliser Communication inter - processus(IPC), Habituellement avec Tuyauterie(Pipe).Instdin
,stdout
Etstderr
Choisissez au moins un des trois pour construire le pipeline .
Supposons que j'utilisestdin
DepythonVersjsTransmission des données,Avecstderr
Réception des données, C'est à peu près comme ça. :
( Le pseudocode suivant n'est qu'indicatif , Pas rigoureusement testé , Utilisation pratique recommandée utilisation directe de la Bibliothèque )
- Créer une nouvelle sous - langue (Supposons queJS)Documentation
python-bridge.js
: Ce fichier est constamment Lustdin
Et selon le message envoyé ,Traitement différent; Et si vous avez besoin d'imprimer un message ou de le transmettre object Pour la langue principale , Les sérialiser correctement et les écrirestdout
Oustderr
.process.stdin.on('data', data => {
data.split('\n').forEach(line => {
// Deal with each line
// write message
process.stdout.write(message + "\n");
// deliver object, "$j2p" can be any prefix predefined and agreed upon with the Python side
// just to tell python side that this is an object needs parsing
process.stderr.write("$j2p sendObj "+JSON.stringify(obj)+"\n);
});
}
process.on('exit', () => {
console.debug('** Node exiting');
});
- InpythonMoyenne,AvecPopen Ouvrir un sous - processus asynchrone , Et au moins un des sous - processus , Par canalisation . C'est comme :
cmd = ["node", "--trace-uncaught", f"{os.path.dirname(__file__)}/python-bridge.js"]
kwargs = dict(
stdin=subprocess.PIPE,
stdout=sys.stdout,
stderr=subprocess.PIPE,
)
if os.name == 'nt':
kwargs['creationflags'] = subprocess.CREATE_NO_WINDOW
subproc = subprocess.Popen(cmd, **kwargs)
- Appelé au besoinJS, Ou besoin de donner JSLors de la transmission des données,Allez.
subproc
Écrire des informations sérialisées , Après l'écritureflush
, Sinon, le tampon pourrait être écrit en premier :subproc.stdin.write(f"$p2j call funcName {json.dumps([arg1, arg2])}".encode())
subproc.stdin.flush() # write immediately, not writing to the buffer of the stream
- Pour la tuyauterie
stdout
/stderr
,Créer un nouveau thread, Dédié à la lecture et au traitement des données transmises . Est la conversion d'un objet en objet , Est l'impression directe d'informations générales au processus principalstderr
Oustdout
.def read_stderr():
while subproc.poll() is None:
# when the subprocess is still alive, keep reading
line = self.subproc.stderr.readline().decode('utf-8')
if line.startswith('$j2p'):
# receive special information
_, cmd, line = line.split(' ', maxsplit=2)
if cmd == 'sendObj':
# For example, received an object
obj = json.loads(line)
else:
# otherwise, write to stderr as it is
sys.stderr.write(line) stderr_thread = threading.Thread(target=read_stderr, args=(), daemon=True)
stderr_thread.start()
C'est à cause de notre
stdout
Aucun tuyau n'a été construit ,Alors...node Par làstdout
Ce qui est imprimé à l'intérieur sera imprimé directement à pythonDesys.stdout
- Oui.,Ne vous en occupez pas vous - même.. - Parce que les fils sont asynchrones , Quand Savez - vous qu'un objet retourné par une fonction est arrivé ? La réponse est de synchroniser les fils ,Sémaphore(Semaphore)、Conditions(Condition),Événements(Event)Attendez un peu!,Tout va bien..ParpythonConditionsPar exemple:
func_name_cv = threading.Condition()
# use a flag and a result object in case some function has no result
func_name_result_returned = False
func_name_result = None def func_name_wrapper(arg1, arg2):
# send arguments
subproc.stdin.write(f"$p2j call funcName {json.dumps([arg1, arg2])}".encode())
subproc.stdin.flush()
# wait for the result
with func_name_cv:
if not func_name_result_returned:
func_name_cv.wait(timeout=10000)
# when result finally returned, reset the flag
func_name_result_returned = False
return func_name_result
En même temps, Besoin de lire stderrLes fils de
read_stderr
Pour débloquer cette valeur de retour .Il est important de noter que,SiJS Duan est sorti par accident. ,subproc
Et mourir., N'oubliez pas d'annuler le blocage dans le fil principal .def read_stderr():
while subproc.poll() is None:
# when the subprocess is still alive, keep reading
# Deal with a line
line = self.subproc.stderr.readline().decode('utf-8')
if line.startswith('$j2p'):
# receive special information
_, cmd, line = line.split(' ', maxsplit=2)
if cmd == 'sendObj':
# acquire lock here to ensure the editing of func_name_result is mutex
with func_name_cv:
# For example, received an object
func_name_result = json.loads(line)
func_name_result_returned = True
# unblock func_name_wrapper when receiving the result
func_name_cv.notify()
else:
# otherwise, write to stderr as it is
sys.stderr.write(line)
# If subproc is terminated (mainly due to error), still need to unblock func_name_wrapper
func_name_cv.notify()
Bien sûr, c'est une version plus simple ,Parce queJS Les appels sont essentiellement linéaires , On peut donc savoir qu'il suffit d'en avoir un objectRetour de,Ça doit être
func_name_wrapper
Résultats correspondants. Si les fonctions sont nombreuses , La situation sera plus compliquée . - Si tu veuxAnnulez.JSConnexion à, Vous devez d'abord fermer le Sous - processus , Et attendez de lire
stdout
/stderr
Les fils de ,Enfin N'oubliez pas de fermer le tuyau .Et L'ordre de ces trois étapes ne peut pas être changé , Si vous fermez d'abord le tuyau , Lire le thread parce questdout
/stderr
C'est fermé et une erreur s'est produite .subproc.terminate()
stderr_thread.join()
subproc.stdin.close()
subproc.stderr.close()
Si c'est le cas, javascriptAppelezpython,C'est la même méthode,javascript Fang Oui. Node.jsEt si,Avecchild_process
Les instructions de .
Avantages
- Tout ce qu'il faut, c'est un montage normal des deux côtés runtime Pour réaliser l'interaction , L'environnement de fonctionnement est relativement bon .
- Tant quepythonFang etjavascript Fang dans leurs runtime Ça va aller. , Il n'y a pas de problème à courir même après .( Sauf en cas de concurrence )
- Tous les paquets d'extension disponibles dans les deux langues sont essentiellement pris en charge .
Inconvénients
- QuandpythonAvecJavaScript Interactions fréquentes , Et quand l'information interactive est grande , Peut affecter l'efficacité du programme . Parce que ce n'est que par 3 Les tuyaux sont mélangés pour traiter les informations générales à imprimer 、pythonAvecjs Objets interactifs 、Appels de fonctions, etc., Les communications coûtent cher .
- Pour qu'un autre sous - processus exécute le Sous - langage runtime, Ça va prendre du temps et de l'espace .
PythonAvecJavascript Explication super détaillée de l'appel mutuel (2022Année1Mise à jour du mois)(Un.)Justification Part 1 - Par sous - processus et communication inter - processus (IPC)Autre article Afghanistan
- IOS ObjectEtjavaScriptAppel mutuel
InIOS Parfois utilisé dans le développement ObjectEtjavaScriptAppel mutuel, Les procédures détaillées sont les suivantes: : 1. ObjectEn coursjavascriptCode, C'est plus simple , Apple offre un excellent moyen de - (NSString ...
- Hybrid AppEn mode développement, IOS/Android Et JavaScript Mode d'appel mutuel
IOS:Objective-C Et JavaScript Appels mutuels iOS7Avant,iOS SDK Pas d'offre Native js Appelez native Code API.Mais UIWebView Un dele ...
- AndroidEtJavaScript Méthode d'appel mutuel
Adresse de reproduction:http://www.jb51.net/article/77206.htm Cet article présente principalementAndroidEtJavaScript Méthode d'appel mutuel , L'exemple analyse AndroidDeWebViewMise en œuvre ...
- androidAvecjavascriptAppel mutuel
La section suivante décrit androidEtjavascript Comment s'appellent - ils les uns les autres? ,Comme ça.UI L'interface est beaucoup plus simple à concevoir ,EtUI Conçu pour traverser les plateformes . Il y a beaucoup de web app La réception est encadrée ,Par exemple,senchaEtjque ...
- Python Notes d'apprentissage de base(Version super détaillée)
1.Variables pythonLa variable moyenne est simple,Il n'est pas nécessaire de spécifier le type de données,Il suffit d'utiliser directement la définition du signe égal.pythonLa variable contient l'adresse mémoire,C'est là que cette valeur existe en mémoire,Si cette variable est assignée à une autre variable, Avant que la nouvelle variable passe ...
- Projet Open SourceScriptGate,DelphiAvecJavaScript Les artefacts qui s'appellent
ScriptGateEst une réalisationTWebBrowserOui.JavaScriptEtDelphi Bibliothèques dont le Code s'appelle mutuellement ,C'est ici.:https://bitbucket.org/freeonterminate/sc ...
- python - Appels mutuels de fonctions Et Champ d'application de la variable
# -*- coding:utf-8 -*- '''@project: [email protected]: [email protected]: study_ Appels mutuels de fonctions et portée des variables [email protected]: PyCharm C ...
- pythonModule-- Comment se rappeler les modules écrits par eux - mêmes
Un.. Deux façons dont les modules s'appellent les uns les autres lorsqu'ils appellent des pairs import module print(module.add(3,8)) from module import add print(add(2,4)) Même ordre ...
- UIWebViewAvecJavaScriptAppel mutuel
UIWebViewAvecJavaScriptCes choses UIWebView- Oui.IOS SDK Contrôle du maillage de rendu moyen , Lors de l'affichage d'une page Web ,On peut.hack La page Web affiche ensuite ce que vous voulez afficher .C'est là quejavascriptOui. ...
- Keras Code très détaillé LSTMDétails de la mise en œuvre
1.Commençons par comprendrekerasDansEmbeddingCouche:from keras.layers.embeddings import Embedding: EmbeddingLes paramètres sont les suivants:: Taille d'entrée:(batc ...
Recommandation aléatoire
- SQLIndex ajouter
EXPLAIN select * from view_agzsaycommont where id >0
- [deviceoneDéveloppement]-Puzzle Games
Un..Introduction Jeux de puzzle , Une image peut être chargée à partir de la galerie locale ,Remplir9- Oui.ImageView, L'autre concerne TimerChronométrage. Contrôle de la Bibliothèque . Chaque grille est le même contrôle , Ajouté dynamiquement à la page d'accueil ,Après initialisation,RéponsetouchÉvénements, Plus tard ...
- Modifierxubuntu14.04( Il en va de même pour ubuntu)En bas.Eclipse Note noire par défaut
Entrée du terminal:sudo gedit /usr/share/themes/Ambiance/gtk-2.0/gtkrc La première ligne voit ce qui suit : gtk-color-scheme = "base_c ...
- JSPDe7Commandes d'action
Les instructions d'action sont différentes des instructions de compilation,Les instructions de compilation sont des notificationsServletInformations sur le traitement du moteur,Et l'action de l'exécution de la connaissance de l'instruction d'action.Les instructions de compilationJSPCompilé enServletÇa marche quand,Les instructions de traitement peuvent généralement être remplacées parJSPScript,Sa connaissanceJSPNormes pour les scripts ...
- Oracle Fonction d'analyse "ORA-30485: Perdu dans la description de la fenêtre ORDER BY Expression"
Plusieurs fonctions d'analyse liées à l'ordre row_number.rank.dense_rank.leadEtlagDeoverDans la fenêtre,Il doit y en avoir un.order_by_clause. D'autres comme :first_value.last_v ...
- wsdlLocation Pouvez - vous écrire la force relative du projet
Si le Code du client utilise wsdlMots générés, Cette adresse vient de wsdlDescription<service>À l'intérieur.<location>Acquis, Si l'adresse de service a été changée pendant le développement , Ça ne peut être modifié qu'à la main. , On dirait qu'il n'y a qu'un seul endroit ...
- GoogleDeJava Utilisation fréquente des bibliothèques de classe Guava
Guava Le chinois signifie Grenade,Le projet est Google Un projet Open source pour,Y compris beaucoup Google Core Java Utilisation fréquente de la Bibliothèque . 1. Outils de base [Basic utilities] UtiliserJava ...
- Insertion Sort List Leetcode
Sort a linked list using insertion sort. J'a i habilement mis en place un noeud de tête temporaire class Solution { public: ListNode* insert ...
- DOCKER De commencer à abandonner(Trois)
Utiliserdocker create [image-name] Créer un conteneur Créer unnginxConteneur miroir, Comme aucun paramètre n'a été spécifié , Paramètres par défaut de l'utilité du conteneur , Ne démarre pas après la création ,Et mettre le récipientIDSortie vers le terminal, S'il n'y a pas de miroir local ...
- animate.cssUtilisation de
Les mots avant animate.cssC'est une utilisationCSS3Deanimation Effets d'animation produits CSSEnsemble, Il y a beaucoup d'animations préférées , Et très simple à utiliser .Cet article détailleraanimate.cssUtilisation de Introduction anim ...