Yazmayı tanımlama arasındaki fark. Dikte ve dikte?


102

Python 3.5'te tip ipuçlarını kullanarak alıştırma yapıyorum. Meslektaşımdan biri typing.Dictşunları kullanıyor :

import typing


def change_bandwidths(new_bandwidths: typing.Dict,
                      user_id: int,
                      user_name: str) -> bool:
    print(new_bandwidths, user_id, user_name)
    return False


def my_change_bandwidths(new_bandwidths: dict,
                         user_id: int,
                         user_name: str) ->bool:
    print(new_bandwidths, user_id, user_name)
    return True


def main():
    my_id, my_name = 23, "Tiras"
    simple_dict = {"Hello": "Moon"}
    change_bandwidths(simple_dict, my_id, my_name)
    new_dict = {"new": "energy source"}
    my_change_bandwidths(new_dict, my_id, my_name)

if __name__ == "__main__":
    main()

İkisi de gayet iyi çalışıyor, bir fark görünmüyor.

typingModül belgelerini okudum .

Arasında typing.Dictveya dicthangisini programda kullanmalıyım?


11
Python'un aslında yazım ipuçlarını zorlamadığını unutmayın . Bunlar sadece ipuçlarıdır , türleri zorlamak için çalışma zamanında veya hatta derleme zamanında kullanılmazlar. Python güçlü bir şekilde yazılabilir (zayıf yazmanın tersi), ayrıca dinamik olarak yazılır (katı yazmanın tersi). Bkz Is Python kesinlikle yazılı? . Mypy gibi harici araçlar, statik analiz adı verilen bir süreçte daha iyi kod yazmanıza yardımcı olmak için bu ipuçlarını kullanabilir.
Martijn Pieters

1
@MartijnPieters MyPy ile birlikte kodumda tip ipuçlarını kullanmayı ve Python'u tip güvenliğiyle kullanabileceğimi düşünerek severdim. Ne yazık ki bana A) <3.4 ve B) üzerinde çalışmayan bir kod aldı, çünkü görünüşe göre tip ipuçları alay konusu oldu. Gerçekten çok talihsiz bir durum.
kedi

3
@cat: Biz çünkü Tip ipucu, bir Facebook çalışanı tarafından Python tanıtıldı muazzam PHP (bkz aynı özelliği eklemek başarıyı hack ). Gülen biri hiçbir zaman bir avuç mühendisle büyük bir proje inşa etmemiştir.
Martijn Pieters

3
@MartijnPieters Hayır, def a(b: int) -> bool:Python 2.7'de bir sözdizimi hatası ve bunun Python 3'ün eski sürümlerinde de bir sözdizimi hatası olduğunu düşünüyorum.
kedi

1
@cat: Burada Python 3.0'a eklenen işlev açıklamalarından bahsediyorsunuz . Yani sözdizimi hatası olan tek sürüm 2.7'dir, bu yüzden mypy bu bilgiyi yorumlara koymayı destekler.
Martijn Pieters

Yanıtlar:


139

Düz kullanmak typing.Dictve dicthayır kullanmak arasında gerçek bir fark yoktur.

Ancak, typing.Dictbir olan Genel tür anahtarların ve değerlerin türünü belirtmenizi sağlar çok daha esnek hale:

def change_bandwidths(new_bandwidths: typing.Dict[str, str],
                      user_id: int,
                      user_name: str) -> bool:

Bu nedenle, proje yaşamınızın bir noktasında sözlük argümanını biraz daha kesin bir şekilde tanımlamak isteyebilirsiniz, bu noktada genişleme typing.Dict, typing.Dict[key_type, value_type]değiştirmekten 'daha küçük' bir değişikliktir dict.

MappingVeya MutableMappingtürlerini kullanarak bunu daha genel hale getirebilirsiniz ; İşlevinizin eşlemeyi değiştirmesi gerekmediğinden, bağlı kalırımMapping . A dictbir eşlemedir, ancak haritalama arayüzünü de tatmin eden başka nesneler yaratabilirsiniz ve işleviniz bunlarla yine de çalışabilir:

def change_bandwidths(new_bandwidths: typing.Mapping[str, str],
                      user_id: int,
                      user_name: str) -> bool:

Şimdi açıkça kod aslında olmayacak bu fonksiyonun diğer kullanıcıları anlatıyorsun değiştirmeknew_bandwidths geçirilen eşleme.

Gerçek uygulamanız yalnızca yazdırılabilir bir nesne beklemektir. Bu bir test uygulaması olabilir, ancak halihazırda kullandıysanız kodunuz çalışmaya devam eder new_bandwidths: typing.Any, çünkü Python'daki herhangi bir nesne yazdırılabilir.


2
Faydalı ek örnekler, sözlük değerlerinin farklı türlerde olabileceği durumlarda olabilir {"name": "bob", "age" : 51}, örneğin , bu böyle bir şey olabilir typing.Mapping[Union[str, int]mi? Ne yuvalanmış bir sözlük hakkında {"person": {"name":"bob", "age": 51}benzer bir şey kabul edeceğini typing.Mapping[str, typing.Mapping[Union[str, int]]? UnionBöyle kullanmak beni rahatsız ediyor çünkü sipariş olmadığı için katı bir şema değil. Belki sorun değil, bir alternatif var mı?
Davos

1
Boşver hakkında Unionsoru ben hala açık bir tartışma olduğunu görmek github.com/python/typing/issues/28
Davos

1
Bu çok ilginç, kullanışlı ve ilgili görünüyor. Python.org/dev/peps/pep-0589
Greg Hilston

@GregHilston: Bu aslında bir sözlüğün hangi anahtarları içerebileceğini ve her bir ilişkili değerin hangi türlere sahip olması gerektiğini nasıl kısıtlayacağınızla ilgilidir.
Martijn Pieters

1
@GregHilston: ah, evet, öyle.
Martijn Pieters

26

typing.Dictşunun genel bir sürümüdür dict:

class typing.Dict(dict, MutableMapping[KT, VT])

Dict'in genel bir versiyonu. Bu tipin kullanımı aşağıdaki gibidir:

def get_position_in_index(word_list: Dict[str, int], word: str) -> int:
     return word_list[word]

Burada, diktedeki anahtar ve değerlerin türünü belirtebilirsiniz: Dict[str, int]

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.