10 पॉइंट द्वारा ilotoki0804 2024-06-01 | 14 टिप्पणियां | WhatsApp पर शेयर करें
  • fieldenum एक ऐसा enum है जिसमें values होती हैं (जिसे instantiate किया जा सकता है).
  • यह Rust के field वाले enum को साफ़-सुथरे तरीके से सपोर्ट करता है.
  • इसने functional programming की purity और Python में practicality के बीच संतुलन बनाने की कोशिश की है.
  • डिफ़ॉल्ट रूप से यह None के विकल्प के रूप में Option और exception के विकल्प के रूप में BoundResult को सपोर्ट करता है.
  • यह पूरी तरह tested है.
  • अभी English documentation कमज़ोर है, लेकिन इसे धीरे-धीरे बेहतर बनाने की योजना है.
  • issue, PR, star जैसी विभिन्न प्रकार की मदद और support का स्वागत है.

14 टिप्पणियां

 
savvykang 2024-06-02

मुझे लगता है dataclass का union type ज़्यादा बेहतर नहीं होगा? declaration छोटा होने के अलावा इसका कोई खास फायदा समझ नहीं आ रहा। क्या fieldenum की कोई ऐसी खास बढ़त है जिससे यह बेहतर हो?

 
ilotoki0804 2024-06-03

घोषणा छोटी, संक्षिप्त और सिर्फ़ ज़रूरी हिस्सों तक सीमित होना भी इसका एक बड़ा फ़ायदा है।
उदाहरण के लिए,

from fieldenum import fieldenum, Variant, Unit  
  
  
@fieldenum  
class Message:  
    Quit = Unit  
    Move = Variant(x=int, y=int)  
    Write = Variant(str)  
    ChangeColor = Variant(int, int, int)  

ऊपर दिए गए fieldenum को अगर dataclass से implement करना हो, तो उसे इस तरह लिखना पड़ेगा।

from dataclasses import dataclass  
from typing import Self  
  
  
class Message:  
    Quit = Self  
    Move = Self  
    Write = Self  
    ChangeColor = Self  
  
  
class QuitMessageClass(Message, metaclass=ParamlessSingletonMeta):  
    pass  
  
QuitMessage = QuitMessageClass()  
  
  
@dataclass(frozen=True, kw_only=True)  
class MoveMessage(Message):  
    x: int  
    y: int  
  
  
@dataclass(frozen=True)  
class WriteMessage(Message):  
    _0: str  
  
  
@dataclass(frozen=True)  
class ChangeColorMessage(Message):  
    _0: int  
    _1: int  
    _2: int  
  
  
Message.Quit = QuitMessage  
Message.Move = MoveMessage  
Message.Write = WriteMessage  
Message.ChangeColor = ChangeColorMessage  

कोड लंबा हो जाता है, पढ़ना भी मुश्किल हो जाता है, गलती की संभावना भी बढ़ जाती है, और यह भी नहीं लगता कि कोड बहुत साफ़-सुथरा है, है ना?

बेशक, इस तरह लिखने पर भी fieldenum द्वारा दिए जाने वाले कई दूसरे फ़ीचर (generic, repr, __fields__, ...) नहीं मिलते।

इसलिए, अगर इन सब चीज़ों को implement करके एक साथ समेटने वाला fieldenum मौजूद हो, तो यह कहीं ज़्यादा सुविधाजनक है।

इसके अलावा, उदाहरण सेक्शन की सामग्री भी देखना उपयोगी हो सकता है।

 
savvykang 2024-06-03
from dataclasses import dataclass  
  
@dataclass(frozen=True) # repr True by default  
class QuitMessage:  
    pass  
  
@dataclass(frozen=True, kw_only=True) # repr True by default  
class MoveMessage:  
    x: int  
    y: int  
  
@dataclass(frozen=True) # repr True by default  
class WriteMessage:  
    _0: str  
  
@dataclass(frozen=True) # repr True by default  
class ChangeColorMessage:  
    _0: int  
    _1: int  
    _2: int  
  
Message = QuitMessage | MoveMessage | WriteMessage | ChangeColorMessage  
  1. dataclass डिफ़ॉल्ट रूप से repr implementation को support करता है
  2. dataclasses.fields field definition के बारे में runtime जानकारी देता है
  3. generics को typing मॉड्यूल के जरिए 3.5 से, और syntactic sugar को 3.12 से support किया गया है
  4. Messages namespace के मामले में, इसे module के रूप में implement किया जा सकता है

फिर भी, class definition के लिए ज़रूरी boilerplate code का न होना, और enum तथा class को एक ही interface के साथ इस्तेमाल कर पाना, इसके फ़ायदे हो सकते हैं। विस्तृत विवरण के लिए धन्यवाद

 
savvykang 2024-06-03

https://stackoverflow.com/a/47784683

इस तरह struct को व्यक्त करने की कई तरह की कोशिशें होती रही हैं, लेकिन आखिरकार इसे Python की सीमा और कमी के रूप में देखा जा सकता है। मैंने ADT (algebraic data type) से पहली बार कॉलेज की कक्षा में OCaml के जरिए परिचय पाया था, लेकिन काम के दौरान इस तरह सिर्फ उसकी नकल ही करनी पड़ती है, यह थोड़ा अफसोसजनक लगता है।

ilotoki जी द्वारा बनाई गई लाइब्रेरी शायद ADT के सबसे करीब पहुंचने वाला उदाहरण मानी जा सकती है। काश किसी दिन यह standard library में शामिल हो और व्यापक रूप से इस्तेमाल की जाए।

 
ilotoki0804 2024-06-03

अगर Message का implementation Union से किया जाए, तो method inheritance का उपयोग नहीं किया जा सकता। उदाहरण के लिए

from fieldenum import fieldenum, Variant, Unit  
  
  
@fieldenum  
class Message:  
    Quit = Unit  
    Move = Variant(x=int, y=int)  
    Write = Variant(str)  
    ChangeColor = Variant(int, int, int)  
  
    def process(self):  
        ...  

ऊपर की तरह .process method जोड़ने पर, सभी variants के लिए .process() method का उपयोग किया जा सकता है।

# Message.process() method हर variant में इस्तेमाल किया जा सकता है  
Message.Quit.process()  
Message.Move(x=123, y=456).process()  
Message.Write("hello, world").process()  
Message.ChangeColor(123, 000, 89).process()  

साथ ही, मैंने जिस repr का ज़िक्र किया था, उसका मतलब था 'उस enum के variant के रूप में repr'।
उदाहरण के लिए, जब fieldenum repr को wrap करके call करता है, तो यह इस तरह काम करता है।

print(repr(Message.Move(x=123, y=456)))  # Message.Move(x=123, y=456)  

अगर custom __repr__ न हो, तो यह बात व्यक्त नहीं होती कि वह Message enum का sub-variant है।

Quit एक unit variant है, इसलिए इसे call किए बिना उपयोग किया जाता है।

Message.Quit  # अलग call (जैसे: `Message.Quit()`) के बिना उपयोग किया जा सकता है  

इसके अलावा, जिन fieldless variants में call का उपयोग करना पड़ता है, उन्हें singleton के रूप में is operator से जाँचा जा सकता है।

from fieldenum import fieldenum, Variant, Unit  
  
class WithFieldless:  
    Fieldless = Variant()  
  
assert WithFieldless.Fieldless() is WithFieldless.Fieldless()  

fieldenum का उपयोग करने पर इस तरह के कई implementation details, जिन्हें आसानी से नज़रअंदाज़ किया जा सकता है, अपने-आप संभालने में मदद मिलती है.

 
wyatt216 2024-06-02

मैं सुझाव देना चाहूँगा कि शायद आप PyCon Korea में इस पर एक प्रस्तुति दें। मुझे यह इतना दिलचस्प लगा कि मैं इसके बनने की प्रक्रिया के दौरान की आपकी कहानी और व्याख्या सीधे आपसे सुनना चाहूँगा!

 
ilotoki0804 2024-06-02

अगर PyCon में प्रस्तुति देने का मौका मिले तो यह मेरे लिए सचमुच सम्मान की बात होगी। हालांकि, सिर्फ मेरी इच्छा से यह संभव होगा या नहीं, यह मुझे नहीं पता(^^;) फिर भी मैं इस पर विचार करूंगा।

 
kayws426 2024-06-01

और यह भी अच्छा होगा कि अंग्रेज़ी README में Option का example भी समझाया जाए।
Option आसानी से समझ में आने वाला है और उसके ज़रिए अपनापन महसूस करना भी आसान होगा। दस्तावेज़ में explanation के क्रम में Option को पहले समझाया जाए तो शायद और बेहतर होगा।

 
ilotoki0804 2024-06-01

अंग्रेज़ी दस्तावेज़ अभी तैयार नहीं हैं, इसलिए वे थोड़े अपूर्ण हैं... कोरियाई दस्तावेज़ पर्याप्त रूप से परिपक्व हो जाने पर मैं उन्हें अंग्रेज़ी में अनुवाद करने की योजना बना रहा हूँ। या फिर संबंधित PR का भी स्वागत है!
मुझे भी लगता है कि पहले Option का परिचय देना बेहतर होगा। मैं इसे संशोधित करूँगा।

 
kayws426 2024-06-01

ओओ। काफ़ी दिलचस्प है!!
आपने जो Korean दस्तावेज़ का example code लिंक किया है, उसमें एक संशोधन है।

from fieldenum import fieldenum, Variant, Unit, unreachable  
from fieldenum.enums import Option  
  
def hello() -> Option:  # GOOD  
    return Option.Some("hello")  
  
def print_hello(option: Option):  # GOOD  
    print(value.unwrap()) #!!!!! 여기에 value가 아니라 option 이어야 할것 같아 보이네요 !!!!!#  
  
value = hello()  
print_hello(value)  
 
ilotoki0804 2024-06-01

बताने के लिए धन्यवाद। मैंने इसे सुधार दिया है!

 
ilotoki0804 2024-06-01

इसे Show GN में पोस्ट करना था, लेकिन गलती से सामान्य के रूप में पोस्ट कर दिया;;

 
moderator 2024-06-01

मैंने इसे संशोधित कर दिया है।

 
ilotoki0804 2024-06-01

धन्यवाद~