Python argparse.Namespace () öğesini sözlük olarak kullanmanın doğru yolu nedir?


228

argparse.ArgumentParser()Bir Namespacenesne olan sonuçlarını sözlük veya eşleme benzeri bir nesne (bkz. Collections.Mapping ) bekleyen bir yöntemle kullanmak istersem , bunu yapmanın doğru yolu nedir?

C:\>python
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> args.baz = 'yippee'
>>> args['baz']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Namespace' object has no attribute '__getitem__'
>>> dir(args)
['__class__', '__contains__', '__delattr__', '__dict__', '__doc__', '__eq__', '_
_format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__
', '__str__', '__subclasshook__', '__weakref__', '_get_args', '_get_kwargs', 'ba
r', 'baz', 'foo']

Bir nesneye "ulaşmak" ve onun __dict__özelliğini kullanmak doğru mudur?

Ben cevap hayır düşünürdüm: __dict__bir arayüz, yol için uygulanması için bir kongre gibi kokuyor, ama __getattribute__ya __setattr__ya __contains__görünmektedir.

Yanıtlar:


386

Ad alanının sözlüğüne vars () ile erişebilirsiniz :

>>> import argparse
>>> args = argparse.Namespace()
>>> args.foo = 1
>>> args.bar = [1,2,3]
>>> d = vars(args)
>>> d
{'foo': 1, 'bar': [1, 2, 3]}

İsterseniz sözlüğü doğrudan değiştirebilirsiniz:

>>> d['baz'] = 'store me'
>>> args.baz
'store me'

Evet, __dict__ özniteliğine erişmek uygundur. İyi tanımlanmış, test edilmiş ve garanti edilmiş bir davranıştır.


1
Dokümanlar şunları söylüyor: "Döndürülen sözlük değiştirilmemeli: karşılık gelen sembol tablosundaki efektler tanımsız." Bu sadece (ya da ya ) davranışını ifade edebilir , ama gerçekten emin değilim. vars()locals()globals()

2
hmm, sanırım vars()ve arasındaki farkı gerçekten anlamıyorum__dict__
Jason S

21
@delnan Birisi dokümanlarda yanlış bir düzenleme yapmış ve aşırı geniş bir uyarı yapmıştı. Dokümanlar daha sonra düzeltildi. Bkz. Docs.python.org/2.7/library/functions.html#vars Salt okunur sözlükleri olan bazı özel durumlar olsa da ( yerel ayarlar ve sınıf sözlüğü vekil sunucuları gibi), vakaların geri kalanı güncellenebilir. Vars (obj) çağrısı eşanlamlı ile obj .__ dict__ olduğunu. Bir argparse ad alanı söz konusu olduğunda , vars (args) güncellenebilir bir sözlüğe doğrudan erişim sağlar.
Raymond Hettinger

1
@RaymondHettinger Tamam, temiz. /3/Dokümanların versiyonundan bu notu aldım (daha yakından inceleme, 3.1 ila 3.4 dahil), bu yüzden düzeltme görünüşte orada eksik.

8
@delnan 3.3 ve 3.3 dokümanlarını yeni güncelledim. Yarın görünür olacak. Gösterdiğiniz için teşekkürler.
Raymond Hettinger

64

Atın ağzından düz :

Özelliklerin dikte benzeri görünümüne sahip olmayı tercih ediyorsanız, standart Python deyimini kullanabilirsiniz vars():

>>> parser = argparse.ArgumentParser()
>>> parser.add_argument('--foo')
>>> args = parser.parse_args(['--foo', 'BAR'])
>>> vars(args)
{'foo': 'BAR'}

- Python Standart Kütüphanesi, 16.4.4.6. Namespace nesnesi


1
Hala 'foo' özlüyor '-'. Bunun hakkında bir fikrin var mı?
user2678074

1
@ user2678074 bu kabuk bayraklarıyla eşleşmek için kasıtlıdır. Kısa çizgiler python yürütme içinde yabancıdır.
Erich

vars(args)verirTypeError: 'dict' object is not callable
user5359531

6
@ user5359531 muhtemelen varsbir değişkenle globalin üzerine yazmışsınızdır . Sen kullanabilirsiniz __builtins__.varsdoğrudan erişmek veya del varsbunu gölgeleme durdurmak için.
Nick T

@NickT Küçük düzeltme: Python işlevleri statik olarak kapsamlıdır, böylece bir işlevdeki genel bir değişkeni gölgelendirirseniz, bu tanımlayıcı, atanmadan önce veya sonra bile her zaman bu işlev içindeki yerel değişkeni ifade eder del. Modül kapsamında At del olacak "un-gölge" yerleşikleri için çalışırlar.
augurar

-1

Bir nesneye "ulaşmak" ve dict özelliğini kullanmak doğru mudur?

Genel olarak "hayır" derdim. Ancak Namespace, muhtemelen sınıflar yerleşik türlerden miras alınamayacağı zaman beni aşırı mühendis olarak etkiledi.

Öte yandan, Namespaceargparse için görev odaklı bir yaklaşım sunuyor ve kapmak için çağrılacak bir durum düşünemiyorum __dict__, ancak hayal gücümün sınırları sizinkiyle aynı değil.


11
__Dict__ özniteliğine erişmek gayet iyi. İçgözlem dil için esastır. Özellik bir nedenden ötürü herkese açık hale getirildi :-)
Raymond Hettinger

8
Ancak Python'daki her şey "herkese açık". Bir örnekte kullanılan uygulama değişkenleri ile sunduğu genel arabirim arasında (önde gelen alt çizgi kuralları hariç) hiçbir ayrım yoktur. Özellikle sözlük benzeri bir nesnede: örnek yöntemleri ile işlev olan sözlük değerleri arasındaki çizgi biraz bulanıktır.
Jason S

Bağımsız değişkenleri adlandırılmış parametre olarak iletiyorsanız? do_something(**args.__dict__)
OrangeDog
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.