Python 3.4+ sürümünde, dict kullanmadığınızda neden Simpletamespace adıyla adlandırılmıştuple kullanmalıyım, çok benzer görünüyorlar


11

Bir noktada, birçok argümanla fonksiyonlar gelebilir. Bazen bazı argümanları süper argümanlarla birleştirmek mantıklıdır. Bunu sık sık dikte ile yaptım, ama şimdi daha iyi yapmanın yollarını arıyorum.

Dönmek istiyorum ...

def do_something(ax, ay, az, bu, bv, c):
    # Do something

... içine ...

def do_something(a, b, c):
    # Do something

... alt değişkenlerini nerede ave biçerdiklerini

Bunu yapmanın bir yolu:

A = namedtuple('A', 'x, y, z')
a = A(ax, ay, az)
B = namedtuple('B', 'u, v')
b = B(bu, bv)

Ancak, bu daha basit görünüyor:

a = SimpleNamespace(x=ax, y=ay, z=az)
b = SimpleNamespace(u=bu, v=bv)

Dezavantajı nedir? Gerçeği ave biyi yazdınız değil mi? Onlar A ve B nesneleri değil mi?

(Btw, değişken adları hakkında endişelenme. Normalde kısa değişken adları olarak kullanmıyorum.)


1
Kendi başına dezavantaj yok, sadece farklı şeyler. Başlangıç ​​için adlandırılmış gruplar değiştirilemezken ad alanları değiştirilebilir. Değişken değişmez olandan daha iyi veya daha kötü mü? İhtiyacınız olan veya istediğiniz şeylere bağlıdır, çoğu durumda önemli değildir. İşlev muhtemelen gerekli özniteliklere sahip herhangi bir nesneyle çalışacaktı, nasıl oluşturulacağı arayana kadar.
Monica'ya zarar vermeyi durdur

@ Goyo Teşekkür ederim. "Dezavantaj" şey bunu söylemek için beceriksiz bir yol oldu. Birinin doğası gereği diğerinden daha iyi olduğunu ima etmek istememiştim. Sadece artılarını ve eksilerini istedim. Tekrar teşekkürler.
André Christoffer Andersen

1
4. satır "b = B (bu, bv)" gibi olmamalı mı?
Alen Siljak

@AlenSiljak Evet olmalı. Şimdi tamir edeceğim.
André Christoffer Andersen

Yanıtlar:


21

SimpleNamespacetemelde bir sözlüğün üstünde güzel bir cephedir. Dizin anahtarları yerine özellikleri kullanmanızı sağlar. Süper esnek ve kullanımı kolay olduğu için bu güzel.

Bu esnekliğin dezavantajı, herhangi bir yapı sağlamamasıdır. Birinin arama yapmasını engelleyecek hiçbir şey yoktur SimpleNamespace(x=ax, y=ay)(ve del a.zbir noktada). Bu örnek işlevinize iletilirse, alana erişmeye çalıştığınızda kural dışı durum oluşur.

Buna karşılık, namedtupleyapılandırılmış bir tür oluşturmanızı sağlar. Tür bir ada sahip olacak ve hangi alanlara sahip olması gerektiğini bilecektir. Bu alanların her biri olmadan bir örnek oluşturamazsınız ve bunlar daha sonra kaldırılamaz. Ayrıca, örnek değiştirilemez, bu nedenle içindeki değerin a.xher zaman aynı olacağını bileceksiniz .

Size SimpleNamespaceveren esnekliğe ihtiyacınız olup olmadığına veya tarafından sağlanan yapı ve garantilere sahip olmayı tercih edip etmediğinize karar vermek size kalmış namedtuple.


2

Yapılandırılmış ve cevapsız cevapları çok seviyorum, bu yüzden aşağıda sadece somut bir örnek sunuyorum.

SimpleNamespaceile başlayan anahtarları kabul eder _. Örneğin, JSON'u alan adlarına sahip nesnelere kontrol etmediğin hızlı ve kolay bir yol arıyorsanız, bu çok kullanışlıdır:

d = {"_id": 2342122, "text": "hi there!"} # Elasticsearch gives this id!
e = SimpleNamespace(**d) # works
Name = namedtuple("Name", sorted(d)) # ValueError so we can't do Name(**d)

Bunun namedtuple, bize SimpleNamespaceasla asla olmayacak ekstra bir nesne verdiğini görebileceğinizi unutmayın . Her SimpleNamespacebiri gerçekten "eşsiz bir kar tanesi", oysa namedtuplesomut değerlerle hiç örneklenmeden var olur. Somut değerler üzerinde genelleme yapan soyutlamalara ihtiyaç duyduğunuz her yerde, muhtemelen tercih etmelisiniz.


1

Özeti SimpleNamespace

Nesneyi oluştururken nitelikleri başlatmaya izin verir:

sn = SimpleNamespace(a=1, b=2)

Okunabilir

repr(): eval(repr(sn)) == sn

Varsayılan karşılaştırmayı geçersiz kılar. İle karşılaştırmak yerine, id()öznitelik değerlerini karşılaştırır.

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.