Définir dynamiquement des fonctions (méthodes) en Python

J'en suis accro, alors j'espère que ça aide quelqu'un.

** Ce que vous essayez de faire **: Définissez une fonction qui affiche dynamiquement trois chemins différents

Puisque l'intérieur de def func est évalué lorsque la fonction est réellement appelée, la valeur de t est la dernière valeur traitée par for.

>>> path_freq = [{"path": "/pickup/6162449", "freq": 1, "name": "a"}, {"path": "/pickup/6162466", "freq": 1, "name": "b"}, {"path": "/pickup/6162461", "freq":1, "name": "c"}]
>>> task_list = {}
>>> for t in path_freq:
...   def func():
...     print(t)
...   task_list.update({func: t['path']})
...
>>> task_list
{<function func at 0x101184848>: '/pickup/6162461', <function func at 0x101184938>: '/pickup/6162466', <function func at 0x1011848c0>: '/pickup/6162449'}
>>> for k,v in task_list.items():
...   k()
...
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}

Essayez quelque chose de similaire dans Ruby

[2] pry(main)> path_freq = [{"path" => "/pickup/6162449", "freq" => 1, "name" => "a"}, {"path" => "/pickup/6162466", "freq" => 1, "name" => "b"}, {"path" => "/pickup/6162461", "freq" => 1, "name" => "c"}]
=> [{"path"=>"/pickup/6162449", "freq"=>1, "name"=>"a"},
 {"path"=>"/pickup/6162466", "freq"=>1, "name"=>"b"},
 {"path"=>"/pickup/6162461", "freq"=>1, "name"=>"c"}]
[3] pry(main)> path_freq.each do |t|
[3] pry(main)*   define_method :hoge do
[3] pry(main)*     puts t
[3] pry(main)*   end
[3] pry(main)*   task_list.merge!({hoge => t})
[3] pry(main)* end
{"path"=>"/pickup/6162449", "freq"=>1, "name"=>"a"}
{"path"=>"/pickup/6162466", "freq"=>1, "name"=>"b"}
{"path"=>"/pickup/6162461", "freq"=>1, "name"=>"c"}
=> [{"path"=>"/pickup/6162449", "freq"=>1, "name"=>"a"},
 {"path"=>"/pickup/6162466", "freq"=>1, "name"=>"b"},
 {"path"=>"/pickup/6162461", "freq"=>1, "name"=>"c"}]
[4] pry(main)> task_list
=> {nil=>{"path"=>"/pickup/6162461", "freq"=>1, "name"=>"c"}}
[5] pry(main)> hoge
{"path"=>"/pickup/6162461", "freq"=>1, "name"=>"c"}
=> nil

Je pensais que Python et Ruby avaient des spécifications de langage similaires, mais je ne pense pas que ce soit le cas. Les méthodes sont traitées comme des objets en Python, mais pas en Ruby. Dans le cas de Ruby, lorsque la méthode hoge est définie par define_method, elle est définie comme la méthode de objet principal dans cet exemple. Vous ne pouvez pas mettre la méthode hoge en tant qu'objet dans un tableau. Au fait, la raison pour laquelle «nil» est inclus dans la clé de task_list est que la valeur de retour des put est «nil» dans Ruby.

Essayez ensuite de définir la méthode d'une autre manière. J'ai essayé d'ajouter une méthode à la classe avec setaddr en Python, mais le comportement était le même.

>>> class Test(): 
...   pass
>>> path_freq = [{"path": "/pickup/6162449", "freq": 1, "name": "a"}, {"path": "/pickup/6162466", "freq": 1, "name": "b"}, {"path": "/pickup/6162461", "freq":
1, "name": "c"}]
>>> task_list = []
>>> for t in path_freq:
...   def func():
...     print(t)
...   setattr(Test, t['name'], func)
...   task_list.append(func)
...
>>> for f in task_list:
...   f()
...
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
>>> for t in path_freq:
...   def func(self):
...     print(t)
...   setattr(Test, t['name'], func)
...
>>> Test().a()
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
>>> Test().b()
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}
>>> Test().c()
{'path': '/pickup/6162461', 'freq': 1, 'name': 'c'}

J'ai essayé de passer la valeur de List par la valeur par défaut de l'argument car la signature de la fonction n'est pas évaluée tardivement.

>>> path_freq = [{"path": "/pickup/6162449", "freq": 1, "name": "a"}, {"path": "/pickup/6162466", "freq": 1, "name": "b"}, {"path": "/pickup/6162461", "freq":1, "name": "c"}]
>>> task_list = {}
>>> for t in path_freq:
...   def func(path=t['path']):
...     print(path)
...   task_list.update({func: t['path']})
...
>>> for k,v in task_list.items():
...   k()
...
/pickup/6162461
/pickup/6162466
/pickup/6162449

:+1:

Recommended Posts

Définir dynamiquement des fonctions (méthodes) en Python
[Python3] Définir dynamiquement des variables globales dans une fonction
Appeler dynamiquement des méthodes en Python
Méthodes d'objet chaîne en Python
Importer dynamiquement des scripts en Python
Remplacer les fonctions de bibliothèque en Python
Fonctions Python apprises avec la chimioinfomatique
Charger dynamiquement les types json avec python
Fonctions Python
Utilisation de variables globales dans les fonctions python
Utilisez facilement vos propres fonctions en Python
Un chercheur d'une société pharmaceutique a résumé les fonctions de Python
Méthodes et champs privés en python [chiffrement]
Nouvelles fonctionnalités de Python 3.4.0 (3) - Fonctions génériques à distribution unique
Comment remplir dynamiquement des zéros avec Python
Résumé des méthodes intégrées, etc. de la liste Python
Quadtree en Python --2
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Méta-analyse en Python
Unittest en Python
Époque en Python
Discord en Python
Allemand en Python
DCI en Python
tri rapide en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
# Bases de Python (fonctions)
FizzBuzz en Python
Sqlite en Python
[Débutant] Fonctions Python
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Fonctions Python faciles à utiliser
Quad-tree en Python
bases de python: fonctions
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Aplatir en python