Dynamischer Proxy mit Python, Ruby, PHP

Einführung

Dieser Artikel ist der 20. Tag des "WACUL Adventskalenders 2016". Kürzlich habe ich den Meta-Programmier-Rubin persönlich zurückgelesen und ihn teilweise bei der Arbeit verwendet ~~ Es gibt kein neues Material, über das ich sprechen könnte ~~, also werde ich dieses Mal über dynamischen Proxy schreiben.

Was ist ein dynamischer Proxy?

Eigentlich bin ich mir nicht sicher, wie häufig dieses Wort vorkommt ... Persönlich "ein Programmiermuster, das den Namen und die Parameter einer undefinierten Methode empfängt und die gewünschte Verarbeitung an ein anderes Objekt delegiert" Ich erkenne das.

Wann zu verwenden

Dies ist nützlich, wenn Sie einen Wrapper für ein externes System schreiben möchten.

Angenommen, Sie möchten eine Clientbibliothek schreiben, die eine externe REST-API verwendet. Der Einfachheit halber beschränken wir uns auf GET.

GET /api/hoge

So führen Sie beispielsweise Anforderungen in Python aus

import requests

class Client:
    def hoge(self):
        return requests.get('/api/hoge')

client = Client()
client.hoge()

Und so weiter. Nichts ist schwierig. In diesem Fall jedoch, wenn Fuga, Piyo usw. zunehmen

class Client:
    def hoge(self):
        return requests.get('/api/hoge')
    def fuga(self):
        return requests.get('/api/fuga')
    def piyo(self):
        return requests.get('/api/piyo')

Es ist schwierig, weil die Anzahl der Kopien zunimmt.

Daher verwenden wir "eine spezielle Methode, die aufgerufen wird, wenn eine Methode oder Eigenschaft nicht gefunden werden kann". Im Fall von Python kann `__ getattr__ `verwendet werden, da die Methoden und Eigenschaften und die Attribute des Objekts identisch sind.

class Client:
    def __getattr__(self, name):
        def _func(*args, **kwargs):
            return requests.get('/api/' + name)
        return _func

Jetzt können Sie client.hoge (), client.fuga () und client.piyo () unterstützen, und das Beste ist, dass Sie die Client-Klasse nicht mehr pflegen müssen, da in Zukunft weitere APIs hinzugefügt werden. Abhängig von der Implementierung von `` _func``` können Sie auch die Parameter verarbeiten, die Sie an client.method übergeben.

Dynamischer Proxy mit Ruby und PHP

Lassen Sie es uns zuerst in Ruby tun. Dieses Mal werde ich method_missing verwenden, da ich nicht nur die Codemenge reduzieren, sondern auch dynamisch unbekannten Spezifikationen entsprechen möchte.

a.rb


class A
  def method_missing(name, *args, &blk)
    p name.to_s
    p args
    return if not block_given?
    blk.call
  end
end

a = A.new
a.hoge
a.fuga(1, 2, 3)
a.piyo do |i, j|
  p "piyopiyo"
end

Wenn Sie es ausführen, sieht es so aus

"hoge"
[]
"fuga"
[1, 2, 3]
"piyo"
[]
"piyopiyo"

Als nächstes kommt PHP. Verwenden Sie `__ call `. Ich erinnerte mich daran, als ich bei der Arbeit schrieb ~~ als es geschrieben wurde ~~. In Kombination mit Reflection fühlt es sich gut an. Für statische Methoden gibt es eine andere Methode namens "__callStatic".

a.php


<?php

class A
{
    public function __call($name, $args)
    {
        var_dump($name);
        var_dump($args);
    }
}

$a = new A();
$a->hoge();
$a->fuga("fugaarg");

Wenn ich es mit cli starte, sieht es so aus

string(4) "hoge"
array(0) {
}
string(4) "fuga"
array(1) {
  [0]=>
  string(7) "fugaarg"
}

Achtung

Wenn Sie es zu oft verwenden, ist der Code in der Regel schwer zu lesen. Verwenden Sie es systematisch.

Recommended Posts

Dynamischer Proxy mit Python, Ruby, PHP
Verwirklichen Sie den PHP / Python-Generator mit Golang / Ruby
Ich habe versucht, Mecab mit Python2.7, Ruby2.3, PHP7 zu verwenden
Java VS PHP VS Python VS Ruby
Zundokokiyoshi mit Python / Rubin / Lua
Über Perl, Python, PHP, Ruby
Lösen mit Ruby und Python AtCoder ABC178 D Dynamische Planungsmethode
Scraping mit Node, Ruby und Python
Überlappende Kombinationen mit Obergrenzen in Python / Ruby / PHP / Golang (Go)
Lösen mit Ruby und Python AtCoder ABC011 C Dynamische Planungsmethode
Lösen mit Ruby und Python AtCoder ABC153 E Dynamische Planungsmethode
Umgang mit regulären Ausdrücken durch PHP / Python
Sende Bild mit Python und speichere mit PHP
PHP / Python / Ruby-Beispiel für die Pfad-API
[Grundlegende Grammatik] Unterschiede zwischen Ruby / Python / PHP
Versuchen Sie, Python von Ruby aus mit Sparsamkeit aufzurufen
Mit Ruby (Rails) verschlüsseln und mit Python entschlüsseln
Einfaches Web-Scraping mit Python und Ruby
FizzBuzz in Python3
Scraping mit Python
Statistik mit Python
Scraping mit Python
Python mit Go
Twilio mit Python
Dynamische Eingabe von Python
In Python integrieren
Spielen Sie mit 2016-Python
AES256 mit Python
Getestet mit Python
Python beginnt mit ()
mit Syntax (Python)
Bingo mit Python
Zundokokiyoshi mit Python
Ich habe versucht, die Mastodon-API mit Ruby (Faraday) / Python (Pycurl) / PHP (Curl) zu erreichen.
Excel mit Python
Mikrocomputer mit Python
Mit Python besetzen
[Verschiedene Bildanalysen mit Plotly] Dynamische Visualisierung mit Plotly [Python, Bild]
[Mit Plotly auf die Karte schreiben] Dynamische Visualisierung mit Plotly [Python]
Gruppierungskombination in Python / Ruby / PHP / Golang (Go)
Serielle Kommunikation mit Python
Zip, entpacken mit Python
Django 1.11 wurde mit Python3.6 gestartet
Primzahlbeurteilung mit Python
Python mit Eclipse + PyDev.
Trends für das Webanwendungs-Framework 2014 (PHP / Java / Ruby / Python / Perl)
Socket-Kommunikation mit Python
Datenanalyse mit Python 2
Scraping in Python (Vorbereitung)
Versuchen Sie es mit Python.
[Docker] Tutorial (Python + PHP)
Dynamische HTML-Seiten mit AWS Lambda und Python
Python lernen mit ChemTHEATER 03
Sequentielle Suche mit Python
"Objektorientiert" mit Python gelernt
Führen Sie Python mit VBA aus
Umgang mit Yaml mit Python
Löse AtCoder 167 mit Python
[Python] Verwenden Sie JSON mit Python
Python lernen mit ChemTHEATER 05-1
Lerne Python mit ChemTHEATER