Adlandırılmış bir gruba kolay bir şekilde dokümantasyon dizisi eklemek mümkün müdür?
Evet, birkaç şekilde.
Alt sınıf yazma.NamedTuple - Python 3.6+
Python 3.6'dan itibaren, doğrudan, bir docstring (ve ek açıklamalar!) İle bir class
tanım kullanabiliriz typing.NamedTuple
:
from typing import NamedTuple
class Card(NamedTuple):
"""This is a card type."""
suit: str
rank: str
Python 2 ile karşılaştırıldığında boş bildirmek __slots__
gerekli değildir. Python 3.8'de alt sınıflar için bile gerekli değildir.
Bildirimin __slots__
boş olamayacağını unutmayın !
Python 3'te, ayrıca adlandırılmış bir çift üzerindeki dokümanı kolayca değiştirebilirsiniz:
NT = collections.namedtuple('NT', 'foo bar')
NT.__doc__ = """:param str foo: foo name
:param list bar: List of bars to bar"""
Bu, yardım çağırdığımızda onlar için niyeti görmemizi sağlar:
Help on class NT in module __main__:
class NT(builtins.tuple)
| :param str foo: foo name
| :param list bar: List of bars to bar
...
Python 2'de aynı şeyi başarmakta karşılaştığımız zorluklarla karşılaştırıldığında bu gerçekten basittir.
Python 2
Python 2'de yapmanız gerekenler
- adlandırılmış grubu alt sınıflara ayırın ve
- bildirmek
__slots__ == ()
Bildirmek __slots__
, buradaki diğer cevapların kaçırdığı önemli bir kısımdır .
Bildirmezseniz __slots__
, örneklere değişken geçici öznitelikler ekleyebilir ve böceklere yol açabilirsiniz.
class Foo(namedtuple('Foo', 'bar')):
"""no __slots__ = ()!!!"""
Ve şimdi:
>>> f = Foo('bar')
>>> f.bar
'bar'
>>> f.baz = 'what?'
>>> f.__dict__
{'baz': 'what?'}
Her örnek ayrı yaratacaktır erişilir (eksikliğini aksi işlevselliği engel olmaz, ancak kayıt düzeni değişmezlik lightweightness ve nitelikleri namedtuples tüm önemli özellikleridir ilan).__dict__
__dict__
__slots__
Ayrıca __repr__
, komut satırında yankılananın size eşdeğer bir nesne vermesini istiyorsanız:
NTBase = collections.namedtuple('NTBase', 'foo bar')
class NT(NTBase):
"""
Individual foo bar, a namedtuple
:param str foo: foo name
:param list bar: List of bars to bar
"""
__slots__ = ()
__repr__
tuple temelini farklı bir adla oluşturursanız buna benzer bir gereklidir (yukarıda ad dizesi bağımsız değişkeniyle yaptığımız gibi 'NTBase'
):
def __repr__(self):
return 'NT(foo={0}, bar={1})'.format(
repr(self.foo), repr(self.bar))
Repr'yi test etmek için, somutlaştırın, ardından bir geçişin eşitliğini test edin eval(repr(instance))
nt = NT('foo', 'bar')
assert eval(repr(nt)) == nt
Belgelerden örnek
Docs ayrıca , ilgili böyle bir örnek vermek __slots__
- Ben buna kendi docstring'ini ekliyorum:
class Point(namedtuple('Point', 'x y')):
"""Docstring added here, not in original"""
__slots__ = ()
@property
def hypot(self):
return (self.x ** 2 + self.y ** 2) ** 0.5
def __str__(self):
return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot)
...
Yukarıda gösterilen alt sınıf __slots__
, boş bir demete ayarlanır . Bu, örnek sözlüklerinin oluşturulmasını engelleyerek bellek gereksinimlerini düşük tutmaya yardımcı olur.
Bu, yerinde kullanımı gösterir (buradaki başka bir yanıtın önerdiği gibi), ancak yerinde kullanımın, yöntem çözümleme sırasına baktığınızda kafa karıştırıcı hale gelebileceğini unutmayın, hata ayıklama yapıyorsanız, bu yüzden başlangıçta Base
bir sonek olarak kullanmayı önerdim çift adlı taban için:
>>> Point.mro()
[<class '__main__.Point'>, <class '__main__.Point'>, <type 'tuple'>, <type 'object'>]
# ^^^^^---------------------^^^^^-- same names!
Onu __dict__
kullanan bir sınıftan alt sınıflandırma yaparken bir alt sınıf oluşturmayı önlemek için , alt sınıfta da bildirmelisiniz. Kullanımla ilgili daha fazla uyarı için bu yanıta__slots__
da bakın .
namedtuple
onu tam teşekküllü bir "nesneye" dönüştürmez mi? Böylece adlandırılmış dizilerden elde edilen bazı performans kazançlarını mı kaybediyorsunuz?