मैं वर्तमान मॉड्यूल पर सेटैट्र () कैसे कॉल करूं?


140

वर्तमान मॉड्यूल पर चर सेट objectकरने के लिए मैं फ़ंक्शन के पहले पैरामीटर " " के रूप में क्या पास करता हूं setattr(object, name, value)?

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

setattr(object, "SOME_CONSTANT", 42);

के रूप में एक ही प्रभाव दे रही है:

SOME_CONSTANT = 42

इन पंक्तियों वाले मॉड्यूल के भीतर (सही के साथ object)।

मैं गतिशील रूप से मॉड्यूल स्तर पर कई मान उत्पन्न कर रहा हूं, और जैसा कि मैं __getattr__मॉड्यूल स्तर पर परिभाषित नहीं कर सकता , यह मेरी गिरावट है।

जवाबों:


220
import sys

thismodule = sys.modules[__name__]

setattr(thismodule, name, value)

या, बिना उपयोग के setattr(जो प्रश्न पत्र को तोड़ता है लेकिन समान व्यावहारिक उद्देश्यों को संतुष्ट करता है;;

globals()[name] = value

नोट : मॉड्यूल दायरे में, बाद के बराबर है:

vars()[name] = value

जो थोड़ा अधिक संक्षिप्त है, लेकिन एक फ़ंक्शन के भीतर से काम नहीं करता है ( vars()गुंजाइश के चर देता है जिसे इसे कहा जाता है: मॉड्यूल के चर जब वैश्विक गुंजाइश पर कहा जाता है, और फिर यह आर / डब्ल्यू का उपयोग करने के लिए ठीक है, लेकिन फ़ंक्शन का है चर जब किसी फ़ंक्शन में बुलाए जाते हैं, और फिर इसे आर / ओ के रूप में माना जाना चाहिए - पायथन ऑनलाइन डॉक्स इस विशिष्ट अंतर के बारे में थोड़ा भ्रमित हो सकता है)।


9
डॉक्स संशोधित वार्स () के बारे में चेतावनी देते हैं। docs.python.org/library/functions.html#vars । ऐसा करना कब ठीक है?

2
@ ~ unutbu, मैं वास्तव में यह नहीं कहूंगा कि यह काफी "ठीक" है, लेकिन यह तब काम करेगा जब आप vars()किसी फ़ंक्शन के अंदर मॉड्यूल-स्तर के दायरे में कॉल करेंगे ।
माइक ग्राहम

4
vars()globals()मॉड्यूल स्कोप के बराबर है (और इसलिए एक सच्चा, परिवर्तनशील तानाशाही देता है) लेकिन locals()फंक्शन स्कोप पर (और इसलिए कभी-कभी-संशोधित छद्म-निर्णय लौटाता है)। मैं vars()मॉड्यूल के दायरे में उपयोग करता हूं क्योंकि यह 3 वर्णों को बचाता है, एक शब्दांश बनाम इसका पर्यायवाची-में-दायरा globals();-)
एलेक्स मार्टेली

14
हां, इसने सबसे महत्वपूर्ण अनुकूलन को नष्ट कर दिया होगा पायथन कंपाइलर करता है: एक फ़ंक्शन के स्थानीय चर को एक हुक्म में नहीं रखा जाता है, वे मूल्यों के एक तंग वेक्टर में हैं, और प्रत्येक स्थानीय चर एक्सेस उस वेक्टर में सूचकांक का उपयोग करता है, नहीं एक नाम की खोज। अनुकूलन को पराजित करने के लिए, आप जिस इच्छा को अस्तित्व में रखने की इच्छा रखते हैं, उसे मजबूर करने के लिए, फ़ंक्शन को प्रारंभ करें exec '': समय एक जोड़े के साथ एक फ़ंक्शन पर्याप्त रूप से लूप करता है, और आप पायथन के प्रदर्शन के लिए इस कोर अनुकूलन के महत्व को देखेंगे।
एलेक्स मार्टेली

3
@msw, मुझे लगता है कि आप "व्यावहारिकता शुद्धता को हराते हैं" भूल गए; ;-)
एलेक्स मार्टेली

6

यदि आपको मॉड्यूल के भीतर से मॉड्यूल स्कॉप्ड वेरिएबल सेट करना चाहिए, तो क्या गलत है global?

# my_module.py

def define_module_scoped_variables():
    global a, b, c
    a, b, c = 'a', ['b'], 3

इस प्रकार:

>>> import my_module
>>> my_module.define_module_scoped_variables()
>>> a
NameError: name 'a' is not defined
>>> my_module.a
'a'
>>> my_module.b
['b']

1
हाँ, मैंने हमेशा (जहां "हमेशा" को "पिछले कुछ महीनों से मैं पायथन सीख रहा था") के रूप में परिभाषित किया गया है, ने global but not reallyघोषणा की कि पज़लिंग। मुझे लगता है कि यह एक ऐतिहासिक अवशेष हो सकता है जो मॉड्यूल नामस्थान से पहले है।
एमएसडब्ल्यू

1
मूल प्रश्न पूछ रहा है कि एक विशेषता को कैसे सेट किया जाए जिसका नाम एक स्ट्रिंग द्वारा दिया गया है (वही चीज जो मैं वर्तमान में खोज रहा था), इसलिए यह मदद नहीं करेगा।
कर्ट


-1
  1. आप नहीं करेंगे तुम करोगेglobals()["SOME_CONSTANT"] = 42
  2. आप नहीं करेंगे आप एक मॉड्यूल के अलावा कहीं और गतिशील रूप से उत्पन्न सामग्री को संग्रहीत करेंगे।

हां, SOME_CONSTANTरन-टाइम पर गणना बिल्कुल स्थिर नहीं है। और यदि globals()आप के लिए उपलब्ध नहीं है, तो आपको इसकी विशेषताओं को संशोधित करने के लिए दूसरे मॉड्यूल में पहुंचना चाहिए; वह लोगों को आश्चर्यचकित करने के लिए बाध्य है।
एमएसडब्ल्यू

3
लगातार और उत्परिवर्ती परस्पर अनन्य हैं। लगातार और गतिशील रूप से उत्पन्न नहीं होते हैं। जो मूल्य मैं उत्पन्न कर रहा हूं, वे हमेशा समान होते हैं, और मेरे हिस्से पर अंकगणित और टाइपिंग को बचाने के लिए, आगे "स्थिरांक" के आधार पर निर्धारित किया जाता है।
मैट जॉइनर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.