Python PHP kompakt (eşdeğer) ve özü ()

5 Cevap php

compact () ve extract () Ben müthiş kullanışlı buluyorum PHP fonksiyonları vardır. compact () sembol tablosunda adlarının bir listesini alır ve sadece kendi değerleri ile bir hashtable oluşturur. özü tersini yapar. örneğin,

$foo = 'what';
$bar = 'ever';
$a = compact('foo', 'bar');
$a['foo']
# what
$a['baz'] = 'another'
extract(a)
$baz
# another

Python aynı yapmak için bir yolu var mı? Bunun üzerine kaşlarını görünüyor ki, ben çevresinde baktım ve ben geldim yakın this thread olduğunu.

I yerliler (), globallerinin () ve vars () hakkında biliyorum, ama nasıl dezavantaj kendi değerleri sadece bir alt kümesini seçebilirsiniz?

Python bu ihtiyacını ortadan kaldırır daha iyi bir şey var mı?

5 Cevap

Çok Pythonic değil, ama gerçekten gerekiyorsa:

import inspect

def compact(*names):
    caller = inspect.stack()[1][0] # caller of compact()
    vars = {}
    for n in names:
        if n in caller.f_locals:
            vars[n] = caller.f_locals[n]
        elif n in caller.f_globals:
            vars[n] = caller.f_globals[n]
    return vars

def extract(vars):
    caller = inspect.stack()[1][0] # caller of extract()
    for n, v in vars.items():
        caller.f_locals[n] = v   # NEVER DO THIS ;-)

İsterseniz bir modül koymak ve işlevleri diyebiliriz. Ben hiç bu Python programlama bir sürü yaptık sert kord Python voodoo ;-) ve - Eğer gerçekten bu işlevleri kullanmak için bir ihtiyaç var hissediyorum ama ciddi, muhtemelen yanlış bir şekilde bir şey yapıyoruz bir kere bu fonksiyonları (iyi, belki de hata ayıklama / otopsi analizi için, ancak normal bir şey) yararlı olacak bir durum içine çalıştırın.

Python hiçbir benzerleri vardır korkuyorum. Bir dereceye kadar, siz (ve geçen) kullanarak kendi etkisini taklit locals yapabilirsiniz:

>>> def compact(locals, *keys):
...     return dict((k, locals[k]) for k in keys)
...
>>> a = 10
>>> b = 2
>>> compact(locals(), 'a', 'b')
{'a': 10, 'b': 2}

>>> def extract(locals, d):
...     for k, v in d.items():
...         locals[k] = v
...
>>> extract(locals(), {'a': 'foo', 'b': 'bar'}
>>> a
'foo'
>>> b
'bar'

Yine de, bu işlevler "son derece kullanışlı" olduğunu sanmıyorum. Dinamik yerel / global değişkenler kötülük ve hata eğilimli - PHP adamlar register_globals cesareti zaman öğrendim. Benim deneyim, birkaç tecrübeli PHP programcıları veya büyük çerçeveler compact() veya extract() kullanın.

Python, explicit is better than implicit:

a = 1
b = 2
# compact
c = dict(a=a, b=b)

# extract
a, b = d['a'], d['b']

Python PHP'nin kompakt fonksiyonu (2.6 ile çalışır; Python önceki sürümleri ile çalışmak garanti değil):

import inspect
def compact(*args):
    return dict([(i, inspect.currentframe().f_back.f_locals.get(i, None)) 
                  for i in args])

Bu konuda daha kapsamlı yazdık: Python can be just as ugly as PHP.

I eşdeğer tahmin extract($x), globals().update(x) olduğu gibi compact() o vars() bir alt bulunuyor

>>> foo, bar, baz = 1, 2, 3
# extract
>>> globals().update({"foo": 4, "qux": 5})
>>> foo
4
>>> qux
5
# compact
>>> d = dict((k, v) for k, v in vars().iteritems() if k in ["foo", "bar"])
>>> d
{'bar': 2, 'foo': 1}