2015-10-28 7 views
6

अनपॅकिंग के लिए कस्टम डबल स्टार ऑपरेटर (**) को कैसे कार्यान्वित करता है, __iter__ एकल स्टार ऑपरेटर (*) के साथ कैसे काम करता है?कक्षा के लिए कस्टम डबल स्टार ऑपरेटर?

उदाहरण के लिए:

class PlayerManager(object): 

    def __init__(self, players=None): 
     self.players = players or [] 

    # Made up method to support ** operator 
    def __dict_iter__(self): 
     for player in self.players: 
      yield get_steamid(player), player 

def print_players(**players): 
    print(players) 

player_manager = PlayerManager([list, of, players]) 
print_players(player_manager) 

आउटपुट:

{ 
    'STEAM_0:0:02201': <Player object at 0x0000000000>, 
    'STEAM_0:0:10232': <Player object at 0x0000000064>, 
    'STEAM_0:0:73602': <Player object at 0x0000000128> 
} 

उत्तर

13

@ShadowRanger कहते हैं, मैपिंग लागू करें।

from collections.abc import Mapping 

class Foo(Mapping): 
    def __iter__(self): 
     yield "a" 
     yield "b" 

    def __len__(self): 
     return 2 

    def __getitem__(self, item): 
     return ord(item) 

f = Foo() 

print(*f) 
print(dict(**f)) 

कार्यक्रम आउटपुट:

a b 
{'a': 97, 'b': 98} 
+0

अति उत्कृष्ट। बहुत बहुत धन्यवाद, पहले कभी 'मैपिंग' के बारे में नहीं सुना था! –

9

लागू Mapping ABC। तकनीकी रूप से, भाषा दस्तावेज़ निर्दिष्ट नहीं करते हैं कि Mapping विधियों का उपयोग किया जाता है, इसलिए मानते हैं कि आपको केवल वर्तमान कार्यान्वयन द्वारा उपयोग किए जाने वाले कुछ सबसेट की आवश्यकता है, यह एक बुरा विचार है। All it says is:

वाक्य रचना ** अभिव्यक्ति समारोह कॉल में प्रकट होता है, अभिव्यक्ति, एक मानचित्रण के लिए मूल्यांकन करना चाहिए जो की सामग्री को अतिरिक्त कीवर्ड तर्क माना जाता है। दोनों अभिव्यक्तियों में दिखाई देने वाले कीवर्ड के मामले में और एक स्पष्ट कीवर्ड तर्क के रूप में, TypeError अपवाद उठाया जाता है।

तो अगर आप Mapping एबीसी को लागू है, तो आप निश्चित रूप से सही इंटरफेस, आदि

FYI करें, है, चाहे वह .items(), प्रत्यक्ष यात्रा और __getitem__ कॉल पर निर्भर करता है की परवाह किए बिना जाँच, CPython में व्यवहार पर 3.5 निश्चित रूप से पर निर्भर कैसे आप Mapping लागू (यदि आप dict से विरासत, यह एक अनुकूलित रास्ता है कि सीधे dict आंतरिक तक पहुँचता है, यदि आप नहीं करते हैं, यह .keys() iterates और प्रत्येक कुंजी को देखता है के रूप में यह हो जाता है का उपयोग करता है)। तो हाँ, कोनों में कटौती मत करो, पूरे एबीसी लागू करें। धन्यवाद Mapping एबीसी और यह के माता-पिता से विरासत में मिला कार्यान्वयन डिफ़ॉल्ट, इस रूप में छोटे रूप में साथ किया जा सकता:

class MyMapping(Mapping): 
    def __getitem__(self, key): 
     ... 
    def __iter__(self): 
     ... 
    def __len__(self): 
     ... 

डिफ़ॉल्ट कार्यान्वयन आप कुछ मामलों में इनकी हो सकता है के वारिस (जैसे items और values अर्द्ध बुराई करना होगा पुनरावृत्ति शामिल है और देखो, जहां प्रत्यक्ष एक्सेसर्स आंतरिक के आधार पर तेज़ी से हो सकते हैं), इसलिए यदि आप इसे अन्य उद्देश्यों के लिए उपयोग कर रहे हैं, तो मैं अनुकूलित संस्करणों वाले लोगों को ओवरराइड करने का सुझाव दूंगा।

+0

आपको बहुत बहुत धन्यवाद, मैं @ codeape का जवाब स्वीकार किए जाते हैं के रूप में यह स्पष्ट रूप से मैं अपने वर्ग समर्थन करने के लिए क्या करने की जरूरत से पता चलता '' ** यहाँ एक उदाहरण है , लेकिन मैंने तुम्हें एक अपवित्र छोड़ दिया! –

+0

@ मार्कसमेसेकान: अजीब। जब आप इसे लिखते थे तो मैं विस्तार से बता रहा था, लेकिन एसओ ने मुझे सूचित नहीं किया (मुझे अभी भी इसके लिए कोई टिप्पणी चेतावनी नहीं है, और वोटों के बाद कुछ मिनट तक प्रतिनिधि दिखाई नहीं दे रहे थे)। एह। जो कुछ। – ShadowRanger

+0

@ShadowRanger: यह जानने के लिए हुआ कि सीपीथन के कौन से बिट इसे कार्यान्वित करते हैं? सी-साइड क्लास – Eric

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