10

purefunction एक गणितीय फ़ंक्शन के समान कार्य है, जहां "असली दुनिया" और साइड इफेक्ट्स के साथ कोई बातचीत नहीं है। देखने के एक और अधिक व्यावहारिक दृष्टिकोण से, इसका मतलब है कि एक शुद्ध समारोह नहीं कर सकते हैं:पायथन में कोई फ़ंक्शन शुद्ध है या नहीं, यह जांचने के लिए कैसे करें?

  • प्रिंट या अन्यथा संदेश
  • यादृच्छिक बनें
  • बदलें वैश्विक चर प्रणाली समय पर निर्भर दिखाने
  • और अन्य

ये सभी सीमाएं शुद्ध कार्य के बारे में कारण बनाना आसान बनाती हैं गैर शुद्ध लोगों की तुलना में। अधिकांश कार्यों को तब शुद्ध होना चाहिए ताकि कार्यक्रम में कम कीड़े हो सकें।

हास्केल जैसे विशाल प्रकार के सिस्टम वाली भाषाओं में पाठक प्रारंभ से पढ़ सकता है अगर कोई फ़ंक्शन है या शुद्ध नहीं है, जिससे लगातार पढ़ने को आसान बना दिया जाता है।

पायथन में यह जानकारी फ़ंक्शन के शीर्ष पर रखे गए @pure सजावट द्वारा अनुकरण की जा सकती है। मैं उस सजावटी को वास्तव में कुछ सत्यापन कार्य करने के लिए भी पसंद करूंगा। मेरी समस्या ऐसे सजावट के कार्यान्वयन में निहित है।

अभी मैं बस ऐसे global या random या print के रूप में कदम उठाए जाने लगे के लिए समारोह के स्रोत कोड देख सकते हैं और अगर यह उनमें से एक पाता है शिकायत।

import inspect 

def pure(function): 
    source = inspect.getsource(function) 
    for non_pure_indicator in ('random', 'time', 'input', 'print', 'global'): 
     if non_pure_indicator in source: 
      raise ValueError("The function {} is not pure as it uses `{}`".format(
       function.__name__, non_pure_indicator)) 
    return function 

हालांकि यह एक अजीब हैक की तरह लगता है, कि या अपनी किस्मत पर निर्भर करता है काम नहीं हो सकता है, आप कृपया मुझे एक बेहतर डेकोरेटर लिखित रूप में मदद कर सकता है?

+3

आप 'test.ourcese' का निरीक्षण कर सकते हैं, फिर 'ast.parse' और नोड्स को विभिन्न चीजों की जांच कर सकते हैं ... लेकिन आप भाषा के अस्तित्व के कारण जा रहे हैं - यदि आप चाहें तो' abc' मॉड्यूल का उपयोग करके देखें सामान, फिर 'isinstance' जांच जहां आवश्यकता हो ... - पायथन ** दृढ़ता से ** टाइप किया गया है - नहीं ** स्थिर रूप से ** टाइप –

+0

@ जोनक्लेमेंट्स गतिशील भाषाएं वास्तव में कम संकलन-समय सत्यापन करती हैं, लेकिन मुझे लगता है कि यह है विशेष जांच कार्यक्रम संगठन को काफी बढ़ाएगी और प्रोग्रामर को अपने काम की समझ को दोबारा जांचेंगी। – Caridorc

+4

फिर एक स्थिर टाइप की गई भाषा का उपयोग करें ... :) आप या तो इसे * खराब * चीज़ या * अच्छी * चीज़ के रूप में देख सकते हैं ... लेकिन यह –

उत्तर

9

मैं देखता हूं कि आप कहां से आ रहे हैं लेकिन मुझे नहीं लगता कि यह काम कर सकता है।आइए एक साधारण उदाहरण लें:

def add(a,b): 
    return a + b 

तो यह शायद आपको "शुद्ध" दिखता है। लेकिन पाइथन में + यहां एक मनमानी फ़ंक्शन है जो कुछ भी कर सकता है, केवल बाध्यकारी के आधार पर जब इसे कहा जाता है। तो a + b मनमाने ढंग से दुष्प्रभाव हो सकता है।

लेकिन इससे भी बदतर है। भले ही यह मानक पूर्णांक + कर रहा हो, फिर भी 'अशुद्ध' सामान चल रहा है।

+ एक नया ऑब्जेक्ट बना रहा है। अब यदि आप सुनिश्चित हैं कि केवल कॉलर के पास उस नई वस्तु का संदर्भ है तो एक ऐसी भावना है जिसमें आप इसे शुद्ध कार्य के रूप में सोच सकते हैं। लेकिन आप यह सुनिश्चित नहीं कर सकते कि, उस वस्तु की निर्माण प्रक्रिया के दौरान, इसका कोई संदर्भ नहीं निकला।

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

class RegisteredNumber(int): 

    numbers = [] 

    def __new__(cls,*args,**kwargs): 
     self = int.__new__(cls,*args,**kwargs) 
     self.numbers.append(self) 
     return self 

    def __add__(self,other): 
     return RegisteredNumber(super().__add__(other)) 

c = RegisteredNumber(1) + 2 

print(RegisteredNumber.numbers) 

यह दिखा देंगे की है कि माना जाता है कि शुद्ध ऐड समारोह वास्तव में RegisteredNumber वर्ग की राज्य बदल दिया है। यह एक बेवकूफ रूप से विकसित उदाहरण नहीं है: मेरे उत्पादन कोड बेस में हमारे पास कक्षाएं हैं जो प्रत्येक निर्मित उदाहरण को ट्रैक करती हैं, उदाहरण के लिए, कुंजी के माध्यम से पहुंच की अनुमति देने के लिए।

शुद्धता की धारणा सिर्फ पायथन में ज्यादा समझ नहीं लेती है।

0

(नहीं एक जवाब है, लेकिन एक टिप्पणी के लिए बहुत लंबा)

तो एक समारोह तर्क का एक ही सेट के लिए अलग मान लौट सकते हैं, तो यह नहीं शुद्ध है?

याद रखें कि अजगर में कार्य वस्तुओं रहे हैं, तो आप एक वस्तु की शुद्धता की जांच करना चाहते ...

इस उदाहरण लें:

def foo(x): 
    ret, foo.x = x*x+foo.x, foo.x+1 
    return ret 
foo.x=0 

foo(3) बार-बार कॉल देता है:

>>> foo(3) 
9 

>>> foo(3) 
10 

>>> foo(3) 
11 

...

इसके अलावा, ग्लोबल्स पढ़ना आपके फ़ंक्शन के अंदर global कथन, या global() बिल्टिन का उपयोग करने की आवश्यकता नहीं है। वैश्विक चर आपके फ़ंक्शन की शुद्धता को प्रभावित करते हुए कहीं और बदल सकते हैं।

उपरोक्त सभी स्थितियों को रनटाइम पर पता लगाना मुश्किल हो सकता है।

+0

दिलचस्प विचार, लेकिन मैं ऐसे कई कार्यों के बारे में सोच सकता हूं जो शुद्ध नहीं हैं जो दिन के घंटे की तरह कम समय के समान लगते हैं, ओ/एस संस्करण संख्या, वर्तमान गिट शाखा, आदि – wallyk

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

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