OVH Cloud OVH Cloud

Copier une fonction

16 réponses
Avatar
Méta-MCI
Bonjour !

J'ai trouvé un moyen pour copier une fonction, avec new.

Exemple :

def fff():
a=1
b=2
c=10
return a+b+c

print fff()
fa=fff
print fa()

import new
titi=new.function(fa.func_code,globals())
print titi()


Seulement, ça ne copie pas les attributs. Pour tester un peu plus, je
chercher un moyen d'adresse l'objet-fonction depuis l'intérieur (de
lui-même), sans indiquer son nom littéralement.

En gros, comment avoir un self ?

Ou, comment avoir l'équivalent de la seconde ligne :
def fff():
this=fff
sans indiquer "fff" ?

(peut-être un truc du genre __func__ ou im_func ou im_self ou
callee(javascript) )

Si vous avez une idée...

@+

Michel Claveau

10 réponses

1 2
Avatar
hg
Méta-MCI wrote:

Bonjour !

J'ai trouvé un moyen pour copier une fonction, avec new.

Exemple :

def fff():
a=1
b=2
c
return a+b+c

print fff()
faÿf
print fa()

import new
titi=new.function(fa.func_code,globals())
print titi()


Seulement, ça ne copie pas les attributs. Pour tester un peu plus, je
chercher un moyen d'adresse l'objet-fonction depuis l'intérieur (de
lui-même), sans indiquer son nom littéralement.

En gros, comment avoir un self ?

Ou, comment avoir l'équivalent de la seconde ligne :
def fff():
thisÿf
sans indiquer "fff" ?

(peut-être un truc du genre __func__ ou im_func ou im_self ou
callee(javascript) )

Si vous avez une idée...

@+

Michel Claveau


Comme ça ?


class test:
def __init__(self,p_a):
self.m_a = p_a
l1 = test(1)
l1
<__main__.test instance at 0xb51adc6c>
l1.m_a
1

import copy

l2 = copy.deepcopy(l1)
l2.m_a
1

hg

Avatar
hg
Méta-MCI wrote:

'soir !

copy.deepcopy va copier une instance (comme dans ton exemple), mais pas
une
fonction (et, comme on ne peut pas instancier une fonction...)

C'est d'ailleurs clairement dit, dans la doc du module copy : "This
version does not copy types like module, class, function, method, stack
trace, stack frame, file, socket, window, array, or any similar types. "

@+

MCI


Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)

hg

Avatar
hg
Méta-MCI wrote:

Re !

Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)


Depuis Python 2.4 (2.3 ?) il est possible d'affecter des attributs aux
objets fonction, indépendament des classes et autres instanciations.

Je cite : "Function objects also support getting and setting arbitrary
attributes, which can be used, for example, to attach metadata to
functions."

Cela peut permettre des trucs intéressants... à découvrir.

@-salutations

Michel Claveau


OK


Avatar
hg
Bruno Desthuilliers wrote:

Méta-MCI wrote:


'soir !

copy.deepcopy va copier une instance (comme dans ton exemple), mais pas
une
fonction (et, comme on ne peut pas instancier une fonction...)

C'est d'ailleurs clairement dit, dans la doc du module copy : "This
version does not copy types like module, class, function, method, stack
trace, stack frame, file, socket, window, array, or any similar types. "

@+

MCI



Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)


Python 2.4.1 (#1, Jul 23 2005, 00:37:37)
[GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on
linux2
Type "help", "copyright", "credits" or "license" for more information.
def toto():
... print "toto"



...
toto.__class__
<type 'function'>



toto.__dict__
{}



toto.__dict__['aaa'] = 'aaa'
toto.aaa
'aaa'








En Python, une fonction est une instance de la classe function.


OK, je suppose qu'il y a des applications ... mais là tout de suite je vois
pas ... mais bon j'utilise jamais de fonctions (15 ans de C ça suffit)

hg




Avatar
Méta-MCI
Re !

J'ai modifié mon code exemple :

def fff():
a=1
b=2
c
return a+b+c

print fff()
faÿf
print fa()

import new,copy
titi=new.function(copy.deepcopy(fa.func_code),globals())
print titi()



Le problème, c'est que, si j'ai une erreur dans le 3e appel ; ligne :
print titi()
Le traceback fait référence à la fonction fff() !!!!

Comme si le copy.deepcopy n'avais pas copié, mais simplement renvoyé un
poiteur sur l'objet-code de la fonction fff

Quelqu'un a une idée ?


Merci d'avance



Michel Claveau

PS : c'est urgent, car l'absence d'explication va gâcher (l'aspect moral de)
mon apéro ! Sinon, je ne vois pas d'autres conséquences...
Avatar
Méta-MCI
'soir !

copy.deepcopy va copier une instance (comme dans ton exemple), mais pas une
fonction (et, comme on ne peut pas instancier une fonction...)

C'est d'ailleurs clairement dit, dans la doc du module copy : "This version
does not copy types like module, class, function, method, stack trace, stack
frame, file, socket, window, array, or any similar types. "

@+

MCI
Avatar
Méta-MCI
Re !

Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)


Depuis Python 2.4 (2.3 ?) il est possible d'affecter des attributs aux
objets fonction, indépendament des classes et autres instanciations.

Je cite : "Function objects also support getting and setting arbitrary
attributes, which can be used, for example, to attach metadata to
functions."

Cela peut permettre des trucs intéressants... à découvrir.

@-salutations

Michel Claveau

Avatar
hg
Bruno Desthuilliers wrote:

Bruno Desthuilliers wrote:



Méta-MCI wrote:



'soir !

copy.deepcopy va copier une instance (comme dans ton exemple), mais pas
une
fonction (et, comme on ne peut pas instancier une fonction...)

C'est d'ailleurs clairement dit, dans la doc du module copy : "This
version does not copy types like module, class, function, method, stack
trace, stack frame, file, socket, window, array, or any similar types.
"

@+

MCI



Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)


Python 2.4.1 (#1, Jul 23 2005, 00:37:37)
[GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on
linux2
Type "help", "copyright", "credits" or "license" for more information.
def toto():
... print "toto"



...
toto.__class__
<type 'function'>



toto.__dict__
{}



toto.__dict__['aaa'] = 'aaa'
toto.aaa
'aaa'








En Python, une fonction est une instance de la classe function.



OK, je suppose qu'il y a des applications ... mais là tout de suite je
vois pas ...


Moi si. Combiné à un décorateur, ça peut être très utile dans un
framework, ie:

class MyController(BaseController):
@action(permissions="edit_object", template="object/edit.tpl")
def edit(self, **params):
# code here


mais bon j'utilise jamais de fonctions


Heu... Tu veux dire que tu copie-colle ton code à la place ???



ben oui, pareil avec les boucles: je suis payé à la ligne de code !

for i in range(1000):
print i

ça fait deux lignes et ça paye peu alors que

print 0
print 1
....
print 999

c'est quand même vachement plus lucratif.

Et puis moi je cut & paste ... c'est + "in"


... Non, je voulais dire que je ne code en general ... non toujours ....
qu'en OO et que donc je ne crée que des méthodes dans des classes /
copy.deepcopy fait mon affaire.

hg






Avatar
Bruno Desthuilliers
Bonjour !

J'ai trouvé un moyen pour copier une fonction, avec new.

Exemple :

def fff():
a=1
b=2
c
return a+b+c

print fff()
faÿf
print fa()

import new
titi=new.function(fa.func_code,globals())
print titi()


Seulement, ça ne copie pas les attributs. Pour tester un peu plus, je
chercher un moyen d'adresse l'objet-fonction depuis l'intérieur (de
lui-même), sans indiquer son nom littéralement.

En gros, comment avoir un self ?


Avec une classe. Une fonction n'est jamais qu'un type qui implémente
__call__ et le protocole descripteur (pour pouvoir être utilisé comme
méthode).

Il y a beaucoup de choses qu'on peut faire en Python sans utiliser la
POO, mais ça reste souvent le moyen le plus simple et le plus efficace.
Par exemple, on peut implémenter l'application partielle très
traditionnellement avec des fonctions et des fermetures, mais c'est (au
moins) aussi simple avec une classe, cf l'implémentation fournie dans la
stdlib de la 2.5.

Mon humble avis...

Avatar
Bruno Desthuilliers
Méta-MCI wrote:


'soir !

copy.deepcopy va copier une instance (comme dans ton exemple), mais pas
une
fonction (et, comme on ne peut pas instancier une fonction...)

C'est d'ailleurs clairement dit, dans la doc du module copy : "This
version does not copy types like module, class, function, method, stack
trace, stack frame, file, socket, window, array, or any similar types. "

@+

MCI



Ce qui me confond dans ta question c'est que tu parles de fonction _et_
d'attributs (que je traduis par variable d'instance ... et donc fonction
devient méthode)


Python 2.4.1 (#1, Jul 23 2005, 00:37:37)
[GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on
linux2
Type "help", "copyright", "credits" or "license" for more information.
def toto():
... print "toto"



...
toto.__class__
<type 'function'>



toto.__dict__
{}



toto.__dict__['aaa'] = 'aaa'
toto.aaa
'aaa'








En Python, une fonction est une instance de la classe function.



1 2