एक छोटा जवाब: उपयोग proxy_tools
proxy_tools
पैकेज प्रदान करने के लिए प्रयास करता है @module_property
कार्यक्षमता।
इसके साथ स्थापित होता है
pip install proxy_tools
@ मरीन के उदाहरण के एक मामूली संशोधन का उपयोग करते हुए, the_module.py
हम डालते हैं
from proxy_tools import module_property
@module_property
def thing():
print(". ", end='') # Prints ". " on each invocation
return 'hello'
अब दूसरी स्क्रिप्ट से, मैं कर सकता हूं
import the_module
print(the_module.thing)
# . hello
अप्रत्याशित व्यवहार
यह समाधान बिना केवेट्स के नहीं है। अर्थात् the_module.thing
है एक स्ट्रिंग नहीं ! यह एक ऐसी proxy_tools.Proxy
वस्तु है जिसके विशेष तरीकों को ओवरराइड किया गया है ताकि यह एक स्ट्रिंग की नकल करे। यहाँ कुछ बुनियादी परीक्षण दिए गए हैं जो इस बात की व्याख्या करते हैं:
res = the_module.thing
# [No output!!! Evaluation doesn't occur yet.]
print(type(res))
# <class 'proxy_tools.Proxy'>
print(isinstance(res, str))
# False
print(res)
# . hello
print(res + " there")
# . hello there
print(isinstance(res + "", str))
# . True
print(res.split('e'))
# . ['h', 'llo']
आंतरिक रूप से, मूल फ़ंक्शन को इसमें संग्रहीत किया जाता है the_module.thing._Proxy__local
:
print(res._Proxy__local)
# <function thing at 0x7f729c3bf680>
आगे के विचार
ईमानदारी से, मैं इस बारे में चकित हूं कि मॉड्यूल में यह कार्यक्षमता क्यों नहीं है। मुझे लगता है कि इस मामले का क्रुक्स वर्ग the_module
का एक उदाहरण है types.ModuleType
। एक "मॉड्यूल संपत्ति" सेट करना इस वर्ग के उदाहरण पर एक संपत्ति स्थापित करने के लिए , बल्कि types.ModuleType
वर्ग पर ही। अधिक जानकारी के लिए, यह उत्तर देखें ।
हम वास्तव types.ModuleType
में निम्नानुसार गुणों को लागू कर सकते हैं, हालांकि परिणाम महान नहीं हैं। हम सीधे निर्मित प्रकारों को संशोधित नहीं कर सकते, लेकिन हम उन्हें शाप दे सकते हैं:
# python -m pip install forbiddenfruit
from forbiddenfruit import curse
from types import ModuleType
# curse has the same signature as setattr.
curse(ModuleType, "thing2", property(lambda module: f'hi from {module.__name__}'))
यह हमें एक संपत्ति देता है जो सभी मॉड्यूल पर मौजूद है। हम सभी मॉड्यूलों में सेटिंग व्यवहार को तोड़ने के बाद से यह थोड़ा सा है:
import sys
print(sys.thing2)
# hi from sys
sys.thing2 = 5
# AttributeError: can't set attribute
__getattr__
एक मॉड्यूल देखें ।