क्या एक आसान तरीके से किसी नेमटुपल में डॉक्यूमेंटेशन स्ट्रिंग जोड़ना संभव है?
हाँ, कई मायनों में।
सबक्लास टाइपिंग ।NamedTuple - पायथन 3.6+
Python 3.6 के रूप में, हम एक class
परिभाषा का उपयोग typing.NamedTuple
सीधे डॉकस्ट्रिंग (और एनोटेशन!) के साथ कर सकते हैं।
from typing import NamedTuple
class Card(NamedTuple):
"""This is a card type."""
suit: str
rank: str
अजगर 2 की तुलना में, खाली घोषित __slots__
करना आवश्यक नहीं है। पायथन 3.8 में, उपवर्गों के लिए भी यह आवश्यक नहीं है।
ध्यान दें कि घोषित __slots__
करना गैर-रिक्त नहीं हो सकता है!
पायथन 3 में, आप किसी नामांक पर आसानी से दस्तावेज़ को बदल सकते हैं:
NT = collections.namedtuple('NT', 'foo bar')
NT.__doc__ = """:param str foo: foo name
:param list bar: List of bars to bar"""
जब हम उन पर इरादे देखने की अनुमति देते हैं, जब हम उन पर सहायता कहते हैं:
Help on class NT in module __main__:
class NT(builtins.tuple)
| :param str foo: foo name
| :param list bar: List of bars to bar
...
यह उन कठिनाइयों की तुलना में वास्तव में सीधा है जहां हमने पायथन 2 में एक ही चीज को पूरा किया है।
अजगर २
पायथन 2 में, आपको इसकी आवश्यकता होगी
- नेकटप्लस उपवर्ग, और
- घोषित
__slots__ == ()
घोषणा __slots__
करना एक महत्वपूर्ण हिस्सा है कि अन्य उत्तर यहां याद आते हैं ।
यदि आप घोषित नहीं करते हैं __slots__
- तो आप बगों को प्रस्तुत करते हुए, उदाहरणों के लिए परिवर्तनशील तदर्थ विशेषताओं को जोड़ सकते हैं।
class Foo(namedtuple('Foo', 'bar')):
"""no __slots__ = ()!!!"""
और अब:
>>> f = Foo('bar')
>>> f.bar
'bar'
>>> f.baz = 'what?'
>>> f.__dict__
{'baz': 'what?'}
एक्सेस किए जाने पर प्रत्येक उदाहरण अलग __dict__
हो जाएगा __dict__
(कमी __slots__
अन्यथा कार्यक्षमता में बाधा नहीं लाएगी, लेकिन टपल की हल्कापन, अपरिवर्तनीयता, और घोषित विशेषताएँ नामांकित की सभी महत्वपूर्ण विशेषताएं हैं)।
आप भी एक चाहते हैं __repr__
, यदि आप चाहते हैं कि कमांड लाइन पर आपको एक समान वस्तु देने के लिए क्या प्रतिध्वनित किया जाए:
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__
इस तरह की जरूरत है अगर आप एक अलग नाम के साथ आधार namedtuple बनाने (जैसे हम नाम स्ट्रिंग तर्क, साथ ऊपर किया 'NTBase'
):
def __repr__(self):
return 'NT(foo={0}, bar={1})'.format(
repr(self.foo), repr(self.bar))
रिप्र का परीक्षण करने के लिए, तुरंत, फिर पास होने की समानता के लिए परीक्षण करें eval(repr(instance))
nt = NT('foo', 'bar')
assert eval(repr(nt)) == nt
प्रलेखन से उदाहरण
डॉक्स भी इस तरह के एक उदाहरण के बारे में देने के लिए, __slots__
- मैं इसे करने के लिए अपने खुद के docstring जोड़ रहा:
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)
...
उपवर्ग __slots__
को एक खाली टपल पर सेट दिखाया गया है । यह उदाहरण शब्दकोशों के निर्माण को रोककर स्मृति आवश्यकताओं को कम रखने में मदद करता है।
यह इन-प्लेस उपयोग को प्रदर्शित करता है (जैसा कि यहां एक अन्य उत्तर बताता है), लेकिन ध्यान दें कि जब आप डिबगिंग कर रहे हैं, तो इन-प्लेस का उपयोग भ्रमित हो सकता है, यदि आप विधि रिज़ॉल्यूशन ऑर्डर को देखते हैं, तो यही कारण है कि मैंने मूल Base
रूप से प्रत्यय के रूप में उपयोग करने का सुझाव दिया है आधार नामित के लिए:
>>> Point.mro()
[<class '__main__.Point'>, <class '__main__.Point'>, <type 'tuple'>, <type 'object'>]
# ^^^^^---------------------^^^^^-- same names!
इसका __dict__
उपयोग करने वाले वर्ग से उप-क्लासिंग के निर्माण को रोकने के लिए , आपको इसे उप-वर्ग में भी घोषित करना होगा। उपयोग करने पर अधिक कैविट्स के लिए यह उत्तर__slots__
भी देखें ।
namedtuple
एक पूर्ण "ऑब्जेक्ट" में परिवर्तित नहीं होगा ? जिससे नाम-टुपल्स से प्रदर्शन के कुछ लाभ खो रहे हैं?