Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Définition de fonction via execfile

3 réponses
Avatar
Eric Masson
'Lut,

Soit une application (un filtre dans le cadre d'un système d'impression
type BSD), contenue dans un seul fichier source, en fonction de
paramètres reçus dans stdin, je dois récupérer des définitions de
fonction dans des fichiers sources externes :

<filtre.py>
def traitement (file, parms):
# blah, blah, blah
# traitement divers et variés sur file
# et création d'un objet quelconque c
if parms['overlay'] <> '' :
fonction_definie_ailleurs(c)

def main():

parameters={}

# Récupération paramètres
textfile, parameters = retrieve_spool_parameters()

# Execution fichier si le paramètre existe
if parameters['overlay'] <> '' :
overlay = '/data/overlays/' + parameters['overlay'] + '.py'
execfile(overlay)

# Traitement
traitement(textfile, parameters)

if __name__ == "__main__":
main()
</filtre.py>

<definition.py>
def fonction_definie_ailleurs(c)
# blah, blah, blah
# Traitement sur c si le paramètre overlay dans stdin était
# definition
</definition.py>

<definition2.py>
def fonction_definie_ailleurs(c)
# blah, blah, blah
# Traitement sur c si le paramètre overlay dans stdin était
# definition2
</definition2.py>

Tant que l'on reste dans la portée de main, fonction définie ailleurs
est définie et connue de l'interpréteur, par contre, l'appel depuis
traitement échoue (changement de portée)

Donc, la question maintenant, est-il possible de contourner ce
comportement et de faire en sorte que fonction_definie_ailleurs soit
définie globalement dans filtre.py et que son code soit chargé
ultérieurement à partir d'un fichier source externe ?

Ou alors est-ce que je devrais me mettre au tricot ?

Merci d'avance

--
D'ailleurs, je me demande a quoi cela sert de "quoter" le texte d'un
autre puisqu'un article a toujours la reference de celui auquel il
repond. Et puis, il y a dejanews.... alors....
-+- CB in: <http://www.le-gnu.net> - T'avais qu'à suivre -+-

3 réponses

Avatar
Bruno Desthuilliers
'Lut,

Soit une application (un filtre dans le cadre d'un système d'impression
type BSD), contenue dans un seul fichier source, en fonction de
paramètres reçus dans stdin, je dois récupérer des définitions de
fonction dans des fichiers sources externes :

<filtre.py>
def traitement (file, parms):


Evite d'utiliser 'file' comme identifiant, à moins que ça ne te dérange
pas de masquer le type standard de même nom.

# blah, blah, blah
# traitement divers et variés sur file
# et création d'un objet quelconque c
if parms['overlay'] <> '' :


On préfère '!=' à '<>' (ce dernier disparaitra dans Python 3,
d'ailleurs). Et dans la mesure où une chaine vide vaut False dans un
test booléen, l'idiome est:

if parms.get('overlay'):

fonction_definie_ailleurs(c)

def main():

parameters={}

# Récupération paramètres
textfile, parameters = retrieve_spool_parameters()

# Execution fichier si le paramètre existe
if parameters['overlay'] <> '' :
overlay = '/data/overlays/' + parameters['overlay'] + '.py'
execfile(overlay)


AMHA, si le but est de rendre une fonction disponible, tu devrais
regarder du côté de __import__


# Traitement
traitement(textfile, parameters)

if __name__ == "__main__":
main()
</filtre.py>

<definition.py>
def fonction_definie_ailleurs(c)
# blah, blah, blah
# Traitement sur c si le paramètre overlay dans stdin était
# definition
</definition.py>

<definition2.py>
def fonction_definie_ailleurs(c)
# blah, blah, blah
# Traitement sur c si le paramètre overlay dans stdin était
# definition2
</definition2.py>

Tant que l'on reste dans la portée de main, fonction définie ailleurs
est définie et connue de l'interpréteur, par contre, l'appel depuis
traitement échoue (changement de portée)

Donc, la question maintenant, est-il possible de contourner ce
comportement et de faire en sorte que fonction_definie_ailleurs soit
définie globalement dans filtre.py et que son code soit chargé
ultérieurement à partir d'un fichier source externe ?


le problème est réel, mais mal formulé. Ce que tu veux, c'est que
traitement() puisse accéder à cette fonction. Ce que tu ne sais
peut-être pas, c'est qu'en Python les fonctions sont des objets comme
les autres - tu peux donc les utiliser comme n'importe quel autre objet.
Entre autres, les passer en argument, les stocker dans une liste ou un
dictionnaire, etc.

Bref, dans la mesure où ta fonction est accessible au moment où tu
appelle traitement(), tu peux la passer à traitement(). En l'occurrence,
le plus simple serait de la stocker dans parametres.

Juste un petit bout de code pour l'exemple:

def main():
def toto(c):
print c

args = dict(toto=toto)
c = "coucou"
titi(c, args)

def titi(c, args):
toto = args.get('toto')
if callable(toto):
toto(c)


Ou alors est-ce que je devrais me mettre au tricot ?


L'un n'exclus pas l'autre !-)

Merci d'avance



Avatar
Eric Masson
Bruno Desthuilliers
writes:

'Lut,

Evite d'utiliser 'file' comme identifiant, à moins que ça ne te
dérange pas de masquer le type standard de même nom.


Euh, c'est du s//g pour cause d'identifiants trop significatifs.

On préfère '!=' à '<>' (ce dernier disparaitra dans Python 3,
d'ailleurs). Et dans la mesure où une chaine vide vaut False dans un
test booléen, l'idiome est:

if parms.get('overlay'):


Tiens, je n'aurais pas pensé à coder ça comme en C, merci du tuyau.

AMHA, si le but est de rendre une fonction disponible, tu devrais
regarder du côté de __import__


Ok.

le problème est réel, mais mal formulé. Ce que tu veux, c'est que
traitement() puisse accéder à cette fonction.


Exact.

Ce que tu ne sais peut-être pas, c'est qu'en Python les fonctions sont
des objets comme les autres - tu peux donc les utiliser comme
n'importe quel autre objet.


Si, j'avais bien compris que c'était le cas, mais par contre, je n'ai
pas les réflexes du développeur Python. Le tout est un script qu'il a
fallu torcher en peu de temps sans se poser de question, et maintenant,
il faut qu'il évolue pour intégrer d'autres fonctionnalités, ce qui
implique de le restructurer de manière à faire quelque chose qui tienne
la route et non pas un méchant plat de spaghettis impossible à
maintenir.

Bref, dans la mesure où ta fonction est accessible au moment où tu
appelle traitement(), tu peux la passer à traitement(). En l'occurrence,
le plus simple serait de la stocker dans parametres.

Juste un petit bout de code pour l'exemple:

def main():
def toto(c):
print c

args = dict(toto=toto)
c = "coucou"
titi(c, args)

def titi(c, args):
toto = args.get('toto')
if callable(toto):
toto(c)


Ok, propre, ça me plait :)

Merci

--
JFM> Au royaume des aveugles le borgne est roi
Au royaume des aveugles les borgnes sont mal vus.
-+- TP in Guide du Neuneu Usenet : Tu t'es vu quand tu fufes -+-


Avatar
Eric Masson
Bruno Desthuilliers
writes:

'Lut,

Evite d'utiliser 'file' comme identifiant, à moins que ça ne te
dérange pas de masquer le type standard de même nom.


Euh, c'est du s///g pour cause d'identifiants trop significatifs.

On préfère '!=' à '<>' (ce dernier disparaitra dans Python 3,
d'ailleurs). Et dans la mesure où une chaine vide vaut False dans un
test booléen, l'idiome est:

if parms.get('overlay'):


Tiens, je n'aurais pas pensé à coder ça comme en C, merci du tuyau.

AMHA, si le but est de rendre une fonction disponible, tu devrais
regarder du côté de __import__


Ok.

le problème est réel, mais mal formulé. Ce que tu veux, c'est que
traitement() puisse accéder à cette fonction.


Exact.

Ce que tu ne sais peut-être pas, c'est qu'en Python les fonctions sont
des objets comme les autres - tu peux donc les utiliser comme
n'importe quel autre objet.


Si, j'avais bien compris que c'était le cas, mais par contre, je n'ai
pas les réflexes du développeur Python. Le tout est un script qu'il a
fallu torcher en peu de temps sans se poser de question, et maintenant,
il faut qu'il évolue pour intégrer d'autres fonctionnalités, ce qui
implique de le restructurer de manière à faire quelque chose qui tienne
la route et non pas un méchant plat de spaghettis impossible à
maintenir.

Bref, dans la mesure où ta fonction est accessible au moment où tu
appelle traitement(), tu peux la passer à traitement(). En l'occurrence,
le plus simple serait de la stocker dans parametres.

Juste un petit bout de code pour l'exemple:

def main():
def toto(c):
print c

args = dict(toto=toto)
c = "coucou"
titi(c, args)

def titi(c, args):
toto = args.get('toto')
if callable(toto):
toto(c)


Ok, propre, ça me plait :)

Merci

--
JFM> Au royaume des aveugles le borgne est roi
Au royaume des aveugles les borgnes sont mal vus.
-+- TP in Guide du Neuneu Usenet : Tu t'es vu quand tu fufes -+-