2009-04-21 6 views
2

Vous cherchez l'équivalent python de cela.Y at-il un équivalent à l'extrait de PHP en Python?

http://php.net/extract

+4

Veuillez modifier la réponse avec les informations complémentaires que vous avez fournies dans le commentaire de la réponse ci-dessous. – Miles

+4

Je ne sais pas pourquoi vous avez choisi la réponse que vous avez choisie. Il est généralement une mauvaise idée de déranger avec les habitants et le déballage du dictionnaire réalise ce dont vous avez besoin et est la façon la plus pythonique. N'importe quelle raison? Je me demandais juste pour savoir de quoi tu avais vraiment besoin. –

+4

Un "+1" pour les Miles et Paolo. Extract et autres tentatives de méta-programmation ressemblant à PHP sont tout simplement effrayantes. Ce sont des failles de sécurité qui attendent de se produire, sans parler des cauchemars de débogage. Certaines des réponses ci-dessous ont fourni de bons conseils sur la façon de procéder, et tandis que David Berger (que vous avez accepté) a donné à l'ancien collège - essayez de répondre à la question de front, d'après ce que j'ai vu de ses réponses sur SO Je doute qu'il utiliserait cette approche dans un code réel, non théorique. –

Répondre

2

On utilise généralement locals() pour y parvenir résultat, mais la fonctionnalité exacte est à vous.

>>> print apple 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
NameError: name 'apple' is not defined 
>>> print banana 
Traceback (most recent call last): 
    File "<stdin>", line 1, in ? 
NameError: name 'banana' is not defined 

>>> variables = {"apple" : "a rigid, juicy fruit", "banana" : "a soft, fleshy fruit"} 
>>> for variable,value in variables.iteritems(): 
... locals()[variable] = value 
... 
>>> print apple 
a rigid, juicy fruit 
>>> print banana 
a soft, fleshy fruit 

EDIT

Merci à tous ceux qui ont diligemment commenté le mauvais état de cette approche. Je suis entièrement d'accord que CECI EST UNE MAUVAISE APPROCHE, et il mérite d'être mentionné dans la réponse réelle pour quiconque trébuche sur cette page. (Ne jamais sous-estimer cela, j'ai vu cette technique dans un extrait de code quelque part.Je peux voir pourquoi dans ce cas particulier c'était inoffensif, mais je sais que je ne peux pas continuer à encourager une mauvaise méthodologie juste parce qu'il y a des situations dans lesquelles pause.)

+8

Les docs Python disent à propos de locals(): "Le contenu de ce dictionnaire ne doit pas être modifié, les changements peuvent ne pas affecter les valeurs des variables locales utilisées par l'interpréteur." http://docs.python.org/library/functions.html En outre, le code qui utilise locals() est généralement plutôt non pythonique; il y a presque toujours une meilleure façon d'écrire des choses. – Miles

+2

Pas downvoting car c'était une tentative honnête de répondre à la question, mais: ne jamais le faire. –

4

pas. Pourquoi en avez-vous besoin?

les instructions suivantes (voir commentaire)

def __api_call__(self, method, resource, **kwargs): 
    print(kwargs) 

def do_call(my_dict): 
    self.__api_call__('POST', '/api/foobar/', **your_dict) # double asterisk! 
+0

def __api_call __ (self, méthode, ressources, ** kwargs): # faire des choses def do_call (my_dict): self .__ api_call __ ('POST', '/ api/foobar /', Existe-t-il une meilleure façon de faire ce que je pense - ne pas vouloir changer l'utilisation de kwargs de __api_call__. – ashchristopher

10

Peut-être que vous seriez mieux expliquer ce que vous essayez de faire. Toute solution à la question directe serait plutôt antipathique car il y a presque certainement une meilleure façon de faire ce que vous voulez.

EDIT (par vos commentaires):

Et en effet, il y a une meilleure façon.

Ce que vous essayez de faire est connu sous le nom unpacking argument lists, et peut être fait comme ceci:

self.__api_call__('POST', '/api/foobar/', **mydict) 

Un exemple de réalisation:

>>> def a_plus_b(a,b): 
...  return a+b 
... 
>>> mydict = {'a':3,'b':4} 
>>> a_plus_b(**mydict) 
7 

Et cela fonctionne aussi avec kwargs, comme vous pouvez attendre:

>>> def a_plus_b(**kwargs): 
...  return kwargs['a'] + kwargs['b'] 
... 
>>> a_plus_b(**mydict) 
7  
0

IMO c'est au moins une bonne question théorique: comment une telle construction peut-elle être mise en œuvre et à quoi cela ressemble-t-il une fois appliqué?

Par exemple, en fonction, il peut être mis en œuvre comme

import inspect 


def extract_attribute(obj, names): 
    if type(names) == str: 
     names = [names] 
    # Get previous frame from the inspect stack. 
    frame = inspect.stack()[1][0] 
    try:   
     frame_locals = frame.f_locals   
     attributes = inspect.getmembers(
      obj, lambda attr: not inspect.ismethod(attr))   
     for name, attribute in attributes: 
      if name.startswith('__') or name.endswith('__'): 
       continue 
      if name in names: 
       frame_locals[name] = attribute 
    finally: 
     del frame 
     del frame_locals 

et utilisé comme

class A(object): 
    foo = 'bar' 


a = A() 
extract_attribute(a, 'foo') 
assert locals()['foo'] == 'bar' 
assert foo == 'bar 

Note: pylint se plaindra attendent sur la dernière ligne. On peut trouver la fonction * extract_attribute * fonctionnant avec un objet de manière similaire à l'importation de fonctionnalités pour les modules. L'appliquer comme couche supplémentaire de couplage de portée (mélangé avec l'importation actuelle) augmentera la complexité du code presque sans exceptions.

PS Il est évident que manipuler suffisamment est un signe de faire quelque chose pour lequel python n'a pas été conçu. Mais les mantras auto-flatteurs comme non-pratique et "non-pythonique" ne sont pas vraiment des arguments appropriés pour moi.En général, il est toujours beaucoup plus "pratique" de faire une expérience et de voir si: 1. La construction va enrichir l'expressivité du langage (par exemple le rendre plus lisible et naturel), donner de nouvelles fonctionnalités, etc. 2 La construction est trop laide et dangereuse à utiliser, trop flexible et dangereuse, les compromis de performance sont inacceptables, etc. L'illustration et le test par exemple explicite sont une alternative préférée. En regardant le code, tout le monde est libre de faire sa propre opinion sans partager les «tripes professionnelles» ou copier-coller des dogmes religieux. S'il vous plaît ne le faites pas.

Questions connexes