2016-11-16 6 views
9

मैं जानना चाहता हूं कि enum और nametuple के बीच अंतर क्या है और जब किसी को एक दूसरे का उपयोग करना चाहिए।enum और nametuple के बीच क्या अंतर है?

+1

ओप पूछने से पहले थोड़ा सा खोजना चाहिए। थीस विषयों को देखें: http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python और http://stackoverflow.com/questions/36932/how-can-i-represent-an -enum-in-python – Kiogara

उत्तर

12

एक सादृश्य (एक अपूर्ण यद्यपि), तो आपको enum रूप enum.Enum और namedtuple अजगर में और सी में struct दूसरे शब्दों में के बारे में सोच सकते हैं, enum रों, अलियासिंग मूल्यों का एक तरीका है, जबकि namedtuple encapsulating का एक तरीका है नाम से डेटा। दोनों वास्तव में विनिमय नहीं कर सकते हैं, और आप enum एस का नाम namedtuple में नामित मानों के रूप में कर सकते हैं।

मुझे लगता है कि यह उदाहरण अंतर को दर्शाता है।

from collections import namedtuple 
from enum import Enum 

class HairColor(Enum): 
    blonde = 1 
    brown = 2 
    black = 3 
    red = 4 

Person = namedtuple('Person', ['name','age','hair_color']) 
bert = Person('Bert', 5, HairColor.black) 

आप उस व्यक्ति के नामित "विशेषताओं" तक पहुंच सकते हैं जैसे आप एक नियमित वस्तु करेंगे।

>>> print(bert.name) 
Bert 
>>> print(bert.age) 
5 
>>> print(bert.hair_color) 
HairColor.black 
>>> print(bert.hair_color.value) 
3 

आप अक्सर इस तरह namedtuple रों दिखाई नहीं दे रहा है क्योंकि एक ही आवश्यक अवधारणा अधिक व्यापक रूप से जाना जाता class घोषणा का उपयोग करके पूरा किया जा सकता है है। class नीचे परिभाषा लगभग namedtuple उपरोक्त परिभाषा के समान व्यवहार करती है।

class Person: 
    def __init__(self, name, age, hair_color): 
     self.name = name 
     self.age = age 
     self.hair_color = hair_color 

हालांकि, एक namedtuple और एक class वस्तु के बीच एक बड़ा अंतर है कि एक namedtuple की विशेषताओं इसके निर्माण के बाद बदला नहीं जा सकता है।

+2

आप 'नामकरण के रूप में एक enum के मानों के रूप में भी उपयोग कर सकते हैं ...' वर्ग लोग (enum.Enum): जॉन = व्यक्ति ('जॉन', 21, HairColor.blonde) ' – Bakuriu

7

namedtuple, एक तेजी संरचना है कि, __dict__ के बजाय __slots__ उपयोग कर रहा है सामग्री उपलब्ध कराने प्रारंभ में (कि व्यावहारिक रूप से केवल, हालांकि एक _replace() विधि मौजूद है पढ़ा हो जाता है) अंतिम रूप।

आमतौर पर एक नाम का उपयोग आमतौर पर किया जाता है जब आपको एक ही प्रकार की सैकड़ों, हजारों और यहां तक ​​कि लाखों) वस्तुओं की आवश्यकता होती है या आप एक रिकॉर्ड पढ़ रहे हैं और/या लिख ​​रहे हैं।
उदाहरण के लिए, अक्सर उद्धृत उदाहरण एक प्वाइंट नामित है जिसे बहुभुज वर्टेक्स के साथ x, y, z घटकों के साथ काम करने के लिए उपयोग किया जा सकता है।
भूमि के ऊपर एक नियमित टपल पर एक namedtuple द्वारा शुरू की कम से कम है हमेशा सूचकांक द्वारा नाम (.x, .y, .z ...) बजाय द्वारा सही घटक की ओर इशारा करते के लाभ की तुलना में अगर (0, 1, 2, ...)।
एएक्स जैसे कोड पढ़ना ए [0] से आसान है: अर्थ स्पष्ट है, कोड लिखने के कुछ महीने बाद और बेहतर, अन्य प्रोग्रामर के लिए भी।

इस प्रकार एक नामकरण तेजी से होता है, जिसका उपयोग ट्यूपल की सामग्री को अर्थपूर्ण रूप से पहचानने के लिए किया जा सकता है, लेकिन अंतिम लेकिन कम से कम नहीं, पुराने कोड के साथ इंडेक्स द्वारा टुपल सामग्री तक पहुंचने के साथ मिल सकता है।

from collections import namedtuple 

Point = namedtuple('Point', 'x y z') # note the x, y, z fields 

origin = Point(0, 0, 0) 

A = Point(1, 1, 1) 
B = Point(1, 1, 0) 
C = Point(1, 0, 0) 
D = Point(1, 2, 3) 

for p in (origin, A, B, C, D): 
    print(p) 
    print('x:', p.x, ' y:', p.y, ' z:', p.z) 
    print('x:', p[0], ' y:', p[1], ' z:', p[2]) 
    print() 

ऊपर के रूप में सब कुछ नाम से बजाय सूचकांक द्वारा अंक घटकों तक पहुँच रहा है उदाहरण से पर जा रहे हैं, जैसे ही, आगे के परिवर्तन और अधिक आसानी से, पेश किया जा सकता है किसी भी सूचकांक नंबर बदलने में नहीं जा रहा द्वारा:

from collections import namedtuple 


Point = namedtuple('Point', 'name x y z') # addition of the field 'name' 

origin = Point('O', 0, 0, 0) 

A = Point('A', 1, 1, 1) 
B = Point('B', 1, 1, 0) 
C = Point('C', 1, 0, 0) 
D = Point('D', 1, 0, 1) 

for p in (origin, A, B, C, D): 
    print(p) 
    print(p.name) # more readable than p[0] that is no more the x coordinate 
    print('x:', p.x, ' y:', p.y, ' z:', p.z) # unchanged 
    print('x:', p[1], ' y:', p[2], ' z:', p[3]) # changed 
    print() 

एक गणना निरंतर मूल्यों के लिए प्रतीकात्मक नामों को जोड़ने और उन्हें एक विशिष्ट सेट के रूप में वर्गीकृत करने का एक तरीका है। हम एनम या इंटिनम से प्राप्त वर्ग बनाकर एक गणना परिभाषित करते हैं, जो हमारे स्थिरांक के मूल्यों के आधार पर है: एनम सामान्य संस्करण है, इंटिनम इस तथ्य को लागू करता है कि प्रत्येक निरंतर मूल्य प्रकार int का होगा।

उदाहरण के लिए, नाम, विशिष्ट पूर्णांक प्रकार, लिंग, या फिर, रंगों को परिभाषित करने के लिए enums अच्छे होते हैं - अधिक आम तौर पर - एक विशिष्ट सेट से संबंधित तत्व।

from enum import Enum, IntEnum, unique 

class Color_1(Enum): 
    red = 'red' 
    green = 'green' 
    blue = 'blue' 

class Color_2(Enum): 
    red = (255, 0, 0) 
    green = (0, 255, 0) 
    blue = (0, 0, 255) 

class Color_3(IntEnum): 
    red = 0xFF0000 
    green = 0xFF00 
    blue = 0xFF 

class Gender_1(Enum): 
    unknown = 'U' 
    male = 'M' 
    female = 'F' 

class Gender_2(Enum): 
    unknown = 0.3 
    male = 0.5 
    female = 0.7 

class Shape(Enum): # Note the different constants types, perfectly legal 
    TRIANGLE = 't' 
    RECTANGLE = 5 
    SQUARE = tuple('square') 

class DataType(IntEnum): 
    int8 = -8 
    int16 = -16 
    int32 = -32 
    int64 = -64 
    int = -2 
    negative = -1 
    positive = 1 
    uint = 2 
    uint8 = 8 
    uint16 = 16 
    uint32 = 32 
    uint64 = 64 

pythonic विकास में - कि, या तो अद्वितीय या नहीं हो सकता अपनी पसंद और विनिर्देश के आधार पर - enumerations तत्वों एक विशिष्ट मूल्य सौंपा पड़ सकता है। अद्वितीय सजावट का उपयोग विशिष्टता को लागू करने के लिए किया जाता है। डिफ़ॉल्ट रूप से, दो या दो से अधिक अलग प्रतीकात्मक नामों के लिए एक ही निरंतर मान असाइन करना संभव है।

class Color_4(IntEnum): 
    red = 1 
    green = 2 
    blue = 3 
    RED = 1 
    GREEN = 2 
    BLUE = 3 

Enumerations तत्वों एक दूसरे के साथ तुलना की जा सकती है, लेकिन उन्हें सफल होने के लिए के लिए, न केवल मूल्य मिलान, बल्कि उनके प्रकार के समान होना चाहिए चाहिए।

उदाहरण के लिए

:

Color_4.red == Color_4.RED 

यह सच है वापस आ जाएगी (एक ही कक्षा, एक ही मूल्य), लेकिन निम्नलिखित:

Shape.SQUARE == tuple('square') 

झूठी होगा - की वजह से तुलना सही तत्व - टपल ('वर्ग') - प्रकार के आकार का नहीं है, हालांकि उनमें से दोनों का एक ही मूल्य है।

निष्कर्ष निकालने के लिए, enums और nametuples विभिन्न यंत्र हैं।

अंक हाल ही में पाइथन (खोज पीईपी 435) में जोड़ा गया है। अगर स्मृति मुझे सही तरीके से सेवा देती है, तो नामित लंबे समय तक नामांकित थे, लेकिन मैं अभी भी एक समुदाय नौसिखिया हूं, इस प्रकार मैं गलत हो सकता हूं। एचटीएच

+0

और इसके विपरीत enums करने के लिए? – Billy

+0

@ बिली क्षमा करें, लेकिन आप यहां आए थे जबकि मैं दूसरे भाग को लिख रहा था जिसे मैंने अभी जोड़ा था। –

+0

'IntEnum' के साथ उपर्युक्त परीक्षण से मैंने देखा है कि निम्नलिखित तुलना' Color_4.red == 1' परिणाम 'True' में होती है। हालांकि, कलर_4 में '1' करते समय इसका परिणाम 'गलत' होता है (केवल को रंग_4 में रंग_4.रेड करने के परिणामस्वरूप 'ट्रू' होगा) – Marc

संबंधित मुद्दे