2010-03-25 12 views
7

मैं पाइथन के लिए बहुत नया हूं, और यह पता लगाने की कोशिश कर रहा हूं कि उस ऑब्जेक्ट को कैसे बनाया जाए, जिसमें गुणों का नाम या इंडेक्स द्वारा पहुंच योग्य हो। उदाहरण के लिए, os.stat() एक stat_result या pwd.getpwnam() देता है जिस तरह से struct_passwd देता है।विशेषता नाम या इंडेक्स विकल्पों द्वारा उपलब्ध संरचना

इसे समझने की कोशिश में, मैं केवल उपर्युक्त प्रकार के सी कार्यान्वयन में आया हूं। विशेष रूप से पायथन में कुछ भी नहीं। इस तरह की वस्तु बनाने के लिए पाइथन मूल तरीका क्या है?

मैं क्षमा चाहता हूं अगर यह पहले से ही व्यापक रूप से कवर किया गया है। एक उत्तर खोजने में, मुझे कुछ मौलिक अवधारणा याद आ रही है जो मुझे जवाब खोजने से बाहर कर रही है।

उत्तर

3

के लिए आप os.stat() और दूसरों के परिणाम वस्तु के रूप में एक ही कार्यान्वयन का उपयोग नहीं कर सकते। हालांकि पायथन 2.6 में एक नया फैक्ट्री फ़ंक्शन है जो नामित टुपल नामक एक समान डेटाटाइप बनाता है। एक नामित टुपल एक टुपल है जिसका स्लॉट भी नाम से संबोधित किया जा सकता है। नामित ट्यूपल को नियमित टुपल की तुलना में, दस्तावेज़ीकरण के अनुसार, किसी और स्मृति की आवश्यकता नहीं होती है, क्योंकि उनके पास प्रति इंस्टेंस डिक्शनरी नहीं है। कारखाने समारोह हस्ताक्षर है:

collections.namedtuple(typename, field_names[, verbose]) 

पहला तर्क नए प्रकार का नाम निर्दिष्ट, दूसरा तर्क एक स्ट्रिंग (अंतरिक्ष या अल्पविराम से अलग) फ़ील्ड नामों से युक्त, अगर वर्बोज़ सच है, है, और अंत में फैक्ट्री फ़ंक्शन भी उत्पन्न कक्षा को प्रिंट करेगा।

उदाहरण

मान लीजिए आप एक टपल एक उपयोगकर्ता नाम और पासवर्ड से युक्त है।स्थिति शून्य पर उपयोगकर्ता नाम आप आइटम मिल तक पहुँचने के लिए और पासवर्ड स्थिति एक पर पहुंचा जा सकता है:

credential = ('joeuser', 'secret123') 
print 'Username:', credential[0] 
print 'Password:', credential[1] 

इस कोड के साथ गलत कुछ भी नहीं है लेकिन टपल स्वयं कुछ दस्तावेज़ीकृत नहीं है। आपको ट्यूपल में फ़ील्ड की स्थिति के बारे में दस्तावेज़ों को ढूंढना और पढ़ना होगा। यह वह जगह है जहां नामित टुपल बचाव के लिए आ सकता है। इस प्रकार हम पिछले उदाहरण पुनःकूटित कर सकते हैं:

import collections 
# Create a new sub-tuple named Credential 
Credential = collections.namedtuple('Credential', 'username, password') 

credential = Credential(username='joeuser', password='secret123') 

print 'Username:', credential.username 
print 'Password:', credential.password 

आप कोड की तरह जब प्रकार बनाने आप तर्क सूची में वर्बोज़ = सच में जोड़ सकते हैं नव निर्मित क्रेडेंशियल-प्रकार के लिए, इस में लग रहा है क्या की रुचि रखते हैं विशेष मामले हम निम्न आउटपुट प्राप्त:

import collections 
Credential = collections.namedtuple('Credential', 'username, password', verbose=True) 

class Credential(tuple):          
    'Credential(username, password)'      

    __slots__ =() 

    _fields = ('username', 'password') 

    def __new__(_cls, username, password): 
     return _tuple.__new__(_cls, (username, password)) 

    @classmethod 
    def _make(cls, iterable, new=tuple.__new__, len=len): 
     'Make a new Credential object from a sequence or iterable' 
     result = new(cls, iterable)         
     if len(result) != 2:           
      raise TypeError('Expected 2 arguments, got %d' % len(result)) 
     return result 

    def __repr__(self): 
     return 'Credential(username=%r, password=%r)' % self 

    def _asdict(t): 
     'Return a new dict which maps field names to their values' 
     return {'username': t[0], 'password': t[1]} 

    def _replace(_self, **kwds): 
     'Return a new Credential object replacing specified fields with new values' 
     result = _self._make(map(kwds.pop, ('username', 'password'), _self)) 
     if kwds: 
      raise ValueError('Got unexpected field names: %r' % kwds.keys()) 
     return result 

    def __getnewargs__(self): 
     return tuple(self) 

    username = _property(_itemgetter(0)) 
    password = _property(_itemgetter(1)) 

नामित टपल केवल नाम से क्षेत्रों के लिए पहुँच प्रदान नहीं करता, लेकिन यह भी इस तरह के _make() फ़ंक्शन जो एक दृश्य से या किसी क्रेडेंशियल उदाहरण बनाकर मदद करता है के रूप में सहायक कार्यों में शामिल है iterable। उदाहरण के लिए:

cred_tuple = ('joeuser', 'secret123') 
credential = Credential._make(cred_tuple) 

namedtuple के लिए अजगर पुस्तकालय प्रलेखन अधिक जानकारी और कोड उदाहरण है, इसलिए मेरा सुझाव है कि आप take a peek.

5

पायथन 2.6 ने collections.namedtuple को यह आसान बनाने के लिए पेश किया। पुराने पायथन संस्करणों के साथ आप named tuple recipe का उपयोग कर सकते हैं।

डॉक्स से सीधे हवाला देते हुए:

>>> Point = namedtuple('Point', 'x y') 
>>> p = Point(11, y=22)  # instantiate with positional or keyword arguments 
>>> p[0] + p[1]    # indexable like the plain tuple (11, 22) 
33 
>>> x, y = p    # unpack like a regular tuple 
>>> x, y 
(11, 22) 
>>> p.x + p.y    # fields also accessible by name 
33 
>>> p      # readable __repr__ with a name=value style 
Point(x=11, y=22) 
0

एक वस्तु मानों सुलभ हैं या तो विशेषता नाम से, या सूचकांक द्वारा

मुझे यकीन है कि आप क्या कर रहे हैं नहीं कर रहा हूँ है इसके बारे में मुश्किल खोजना।

सूचकांक द्वारा उपलब्ध एक संग्रह __getitem__ लागू करता है।

नामों द्वारा सुलभ एक संग्रह __getattr__ (या __getattribute__) लागू करता है।

आप बिना किसी परेशानी के दोनों को कार्यान्वित कर सकते हैं। या, आप namedtuple का उपयोग कर सकते हैं।

जीवन को आसान बनाने के लिए, आप tuple कक्षा का विस्तार कर सकते हैं ताकि आपको अपना __getitem__ लागू नहीं करना पड़े। या आप एक साधारण कक्षा को परिभाषित कर सकते हैं जिसमें __getitem__ भी है, इसलिए आपको __getattr__ के साथ गड़बड़ नहीं करना पड़ेगा।

उदाहरण

>>> class Foo(object): 
...  def __init__(self, x, y, z): 
...   self.x= x 
...   self.y= y 
...   self.z= z 
...  def __getitem__(self, index): 
...   return { 0: self.x, 1: self.y, 2: self.z }[index] 
... 
>>> f= Foo(1,2,3) 
>>> f.x 
1 
>>> f[0] 
1 
>>> f[1] 
2 
>>> f[2] 
3 
>>> f.y 
2 
संबंधित मुद्दे