टीएल; डॉ: संपत्ति सजावटी कक्षा-स्तर की फ़ंक्शन परिभाषाओं के साथ कैसे काम करते हैं, लेकिन मॉड्यूल-स्तरीय परिभाषाओं के साथ नहीं?संपत्ति सजावट केवल कक्षाओं के लिए परिभाषित क्यों है?
मैं कुछ मॉड्यूल-स्तरीय कार्यों के लिए संपत्ति सजावटी लगा रहा था, सोच रहा था कि वे मुझे केवल विशेषता लुकअप द्वारा विधियों को आमंत्रित करने की अनुमति देंगे।
यह विशेष रूप से आकर्षक था, क्योंकि मैं get_port
तरह विन्यास कार्यों का एक सेट को परिभाषित किया गया था, get_hostname
, आदि, जो सभी के अपने सरल, अधिक संक्षिप्त संपत्ति समकक्षों के साथ प्रतिस्थापित किया जा सकता था: port
, hostname
, आदि
इस प्रकार, config.get_port()
सिर्फ होगा बहुत अच्छे config.port
मैं हैरान था जब मैं निम्नलिखित ट्रैसबैक पाया, साबित है कि यह एक व्यवहार्य विकल्प नहीं था:
TypeError: int() argument must be a string or a number, not 'property'
मुझे पता था कि मैंने मॉड्यूल-स्तर पर संपत्ति जैसी कार्यक्षमता के लिए कुछ उदाहरण देखा था, क्योंकि मैंने इसे सुरुचिपूर्ण लेकिन हैकी pbs library का उपयोग करके शैल कमांड स्क्रिप्ट के लिए उपयोग किया था।
नीचे दिलचस्प दिलचस्प हैक pbs library source code में पाया जा सकता है। यह मॉड्यूल-स्तर पर संपत्ति-जैसी विशेषता लुकअप करने की क्षमता को सक्षम बनाता है, लेकिन यह बेहद खतरनाक हैकिश है।
# this is a thin wrapper around THIS module (we patch sys.modules[__name__]).
# this is in the case that the user does a "from pbs import whatever"
# in other words, they only want to import certain programs, not the whole
# system PATH worth of commands. in this case, we just proxy the
# import lookup to our Environment class
class SelfWrapper(ModuleType):
def __init__(self, self_module):
# this is super ugly to have to copy attributes like this,
# but it seems to be the only way to make reload() behave
# nicely. if i make these attributes dynamic lookups in
# __getattr__, reload sometimes chokes in weird ways...
for attr in ["__builtins__", "__doc__", "__name__", "__package__"]:
setattr(self, attr, getattr(self_module, attr))
self.self_module = self_module
self.env = Environment(globals())
def __getattr__(self, name):
return self.env[name]
नीचे आयात नेम स्पेस में इस वर्ग सम्मिलित करने के लिए कोड है। यह वास्तव में सीधे sys.modules
पैच करता है!
# we're being run as a stand-alone script, fire up a REPL
if __name__ == "__main__":
globs = globals()
f_globals = {}
for k in ["__builtins__", "__doc__", "__name__", "__package__"]:
f_globals[k] = globs[k]
env = Environment(f_globals)
run_repl(env)
# we're being imported from somewhere
else:
self = sys.modules[__name__]
sys.modules[__name__] = SelfWrapper(self)
अब मैंने देखा है कि क्या लंबाई pbs
माध्यम से जाना है, मैं सोच क्यों अजगर की इस सुविधा भाषा में सीधे नहीं ले सकता छोड़ रहा हूँ। विशेष रूप से property
सजावटी ऐसी कार्यक्षमता जोड़ने के लिए एक प्राकृतिक जगह की तरह लगता है।
क्या कोई पक्षपातपूर्ण कारण या प्रेरणा है कि यह सीधे क्यों नहीं बनाया गया है?
आसान खोज के लिए: अब एक मॉड्यूल है जिसे mprop कहा जाता है जो यह आपके लिए करता है https://pypi.python.org/pypi/mprop – AbdealiJK