Config.py में वैश्विक विन्यास चर प्रदान करने का सबसे पाइथोनिक तरीका है? [बन्द है]


98

सरल सामान को अधिक जटिल बनाने में मेरी अंतहीन खोज में, मैं पायथन अंडे के पैकेज में पाए जाने वाले विशिष्ट ' config.py ' के अंदर वैश्विक कॉन्फ़िगरेशन चर प्रदान करने के लिए सबसे 'पायथोनिक' तरीके पर शोध कर रहा हूं ।

पारंपरिक तरीका (आह, अच्छा राजभाषा # #ffine !) इस प्रकार है:

MYSQL_PORT = 3306
MYSQL_DATABASE = 'mydb'
MYSQL_DATABASE_TABLES = ['tb_users', 'tb_groups']

इसलिए वैश्विक चर निम्नलिखित तरीकों में से एक में आयात किए जाते हैं:

from config import *
dbname = MYSQL_DATABASE
for table in MYSQL_DATABASE_TABLES:
    print table

या:

import config
dbname = config.MYSQL_DATABASE
assert(isinstance(config.MYSQL_PORT, int))

यह समझ में आता है, लेकिन कभी-कभी थोड़ा गड़बड़ हो सकता है, खासकर जब आप कुछ चर के नामों को याद करने की कोशिश कर रहे हों। इसके अलावा, विशेषताओं के रूप में चर के साथ एक 'कॉन्फ़िगरेशन' ऑब्जेक्ट प्रदान करना , अधिक लचीला हो सकता है। तो, bpython config.py फ़ाइल से लीड लेते हुए , मैं साथ आया:

class Struct(object):

    def __init__(self, *args):
        self.__header__ = str(args[0]) if args else None

    def __repr__(self):
        if self.__header__ is None:
             return super(Struct, self).__repr__()
        return self.__header__

    def next(self):
        """ Fake iteration functionality.
        """
        raise StopIteration

    def __iter__(self):
        """ Fake iteration functionality.
        We skip magic attribues and Structs, and return the rest.
        """
        ks = self.__dict__.keys()
        for k in ks:
            if not k.startswith('__') and not isinstance(k, Struct):
                yield getattr(self, k)

    def __len__(self):
        """ Don't count magic attributes or Structs.
        """
        ks = self.__dict__.keys()
        return len([k for k in ks if not k.startswith('__')\
                    and not isinstance(k, Struct)])

और एक 'config.py' जो वर्ग को आयात करता है और निम्नानुसार पढ़ता है:

from _config import Struct as Section

mysql = Section("MySQL specific configuration")
mysql.user = 'root'
mysql.pass = 'secret'
mysql.host = 'localhost'
mysql.port = 3306
mysql.database = 'mydb'

mysql.tables = Section("Tables for 'mydb'")
mysql.tables.users = 'tb_users'
mysql.tables.groups =  'tb_groups'

और इस तरह से उपयोग किया जाता है:

from sqlalchemy import MetaData, Table
import config as CONFIG

assert(isinstance(CONFIG.mysql.port, int))

mdata = MetaData(
    "mysql://%s:%s@%s:%d/%s" % (
         CONFIG.mysql.user,
         CONFIG.mysql.pass,
         CONFIG.mysql.host,
         CONFIG.mysql.port,
         CONFIG.mysql.database,
     )
)

tables = []
for name in CONFIG.mysql.tables:
    tables.append(Table(name, mdata, autoload=True))

जो एक पैकेज के अंदर वैश्विक चरों को संग्रहीत करने और लाने के लिए अधिक पठनीय, अभिव्यंजक और लचीला तरीका लगता है।

सबसे बड़ा विचार कभी? इन स्थितियों का मुकाबला करने के लिए सबसे अच्छा अभ्यास क्या है? आपके पैकेज के अंदर वैश्विक नाम और चर संग्रहीत करने और लाने का आपका तरीका क्या है ?


3
आपने पहले ही यहाँ एक निर्णय ले लिया है जो अच्छा हो भी सकता है और नहीं भी। कॉन्फिडेंस को अलग-अलग तरीके से स्टोर किया जा सकता है, जैसे JSON, XML, अलग-अलग ग्रामर के लिए * nixes और Windows इत्यादि। कौन कॉन्फ़िगर फ़ाइल (एक उपकरण, एक मानव, क्या पृष्ठभूमि?) पर निर्भर करता है विभिन्न व्याकरण बेहतर हो सकता है। बहुधा यह एक अच्छा विचार नहीं हो सकता है कि जिस फाइल को आप अपने प्रोग्राम के लिए उपयोग करते हैं, उसी भाषा में कॉन्फिग फाइल को लिखने दें, क्योंकि यह उपयोगकर्ता को बहुत अधिक शक्ति देता है (जो खुद हो सकता है, लेकिन आप खुद ही वह सब कुछ याद नहीं रख सकते हैं जो कर सकते हैं कुछ महीने आगे बढ़ें)।
एरिकबवर्क

4
अक्सर मैं एक JSON कॉन्फ़िग फ़ाइल लिखना समाप्त करता हूं। यह आसानी से अजगर संरचनाओं में पढ़ा जा सकता है और एक उपकरण द्वारा भी बनाया जा सकता है। ऐसा लगता है कि सबसे अधिक लचीलापन है और केवल लागत कुछ ब्रेसिज़ हैं जो उपयोगकर्ता को परेशान कर सकते हैं। मैंने कभी एग नहीं लिखा, हालांकि। शायद यही मानक तरीका है। उस मामले में सिर्फ मेरी टिप्पणी को नजरअंदाज करें।
एरिकबवर्क

1
आप "स्वयं .__
तानाशाह

1
के संभावित डुप्लिकेट क्या अजगर में एक सेटिंग फ़ाइल का उपयोग सबसे अच्छा अभ्यास है? वे जवाब देते हैं "कई तरीके संभव हैं, और एक बिकने वाला धागा पहले से मौजूद है। जब तक आप सुरक्षा के बारे में परवाह नहीं करते हैं। config.py अच्छा है।"
निकाना रेक्लाविक्स 3

मैंने इसका उपयोग करना समाप्त कर दिया python-box, यह उत्तर
विकसित

जवाबों:


4

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


6
basicconfig.pyफ़ाइल के लिए भेजा में ले जाया गया है लगता है के लिए github.com/kdart/pycopia/blob/master/core/pycopia/...
पॉल एम Furley

मुझे पता है कि यह कुछ साल पुराना है, लेकिन मैं एक शुरुआत कर रहा हूं और मुझे लगता है कि यह कॉन्फिग फाइल अनिवार्य रूप से वह है जो मैं खोज रहा हूं (शायद बहुत उन्नत), और मैं इसे बेहतर तरीके से समझना चाहूंगा। क्या मैं केवल ConfigHolderउन मॉड्यूल्स के एक हुक के साथ इनिशियलाइज़ कर सकता हूं, जिन्हें मैं मॉड्यूल के बीच सेट और पास करना चाहता हूं?
जिंक्स

@Jinx इस बिंदु पर मैं (और वर्तमान में उपयोग कर रहा हूँ) एक YAML फ़ाइल और विन्यास के लिए PyYAML। मैं थर्ड-पार्टी मॉड्यूल का भी उपयोग करता हूं जिसे कॉल किया जाता है confitऔर यह कई स्रोतों को मर्ज करने का समर्थन करता है। यह एक नए devtest.config मॉड्यूल का हिस्सा है ।
कीथ

56

इस तरह से बिल्ट-इन प्रकारों का उपयोग करने के बारे में कैसे:

config = {
    "mysql": {
        "user": "root",
        "pass": "secret",
        "tables": {
            "users": "tb_users"
        }
        # etc
    }
}

आप निम्नानुसार मानों तक पहुँच सकते हैं:

config["mysql"]["tables"]["users"]

यदि आप अपने कॉन्फिग ट्री के अंदर भावों की गणना करने की क्षमता का त्याग करने के लिए तैयार हैं, तो आप YAML का उपयोग कर सकते हैं और इस तरह से अधिक पठनीय कॉन्फिग फ़ाइल के साथ समाप्त हो सकते हैं :

mysql:
  - user: root
  - pass: secret
  - tables:
    - users: tb_users

और conyiently पार्स और पहुँच फ़ाइल का उपयोग करने के लिए PyYAML जैसी लाइब्रेरी का उपयोग करें


लेकिन आम तौर पर आप अलग-अलग विन्यास फाइल रखना चाहते हैं और इस प्रकार आपके कोड के अंदर कोई विन्यास डेटा नहीं होता है। तो SONconfig´ एक बाहरी JSON / YAML फाइल होगी जिसे आपको हर बार जब आप इसे एक्सेस करना चाहते हैं, तो इसे हर एक क्लास में डिस्क से लोड करना होगा। मेरा मानना ​​है कि सवाल "एक बार लोड करने" का है और लोड किए गए डेटा तक वैश्विक जैसी पहुंच है। आपके द्वारा सुझाए गए समाधान के साथ आप ऐसा कैसे करेंगे?
मासी

3
अगर स्मृति में डेटा रखने के लिए बस कुछ मौजूद होगा ^ ^
सिनेमाई

16

मुझे छोटे अनुप्रयोगों के लिए यह समाधान पसंद है :

class App:
  __conf = {
    "username": "",
    "password": "",
    "MYSQL_PORT": 3306,
    "MYSQL_DATABASE": 'mydb',
    "MYSQL_DATABASE_TABLES": ['tb_users', 'tb_groups']
  }
  __setters = ["username", "password"]

  @staticmethod
  def config(name):
    return App.__conf[name]

  @staticmethod
  def set(name, value):
    if name in App.__setters:
      App.__conf[name] = value
    else:
      raise NameError("Name not accepted in set() method")

और फिर उपयोग है:

if __name__ == "__main__":
   # from config import App
   App.config("MYSQL_PORT")     # return 3306
   App.set("username", "hi")    # set new username value
   App.config("username")       # return "hi"
   App.set("MYSQL_PORT", "abc") # this raises NameError

.. आपको यह पसंद आना चाहिए क्योंकि:

  • वर्ग चर का उपयोग करता है (कोई ऑब्जेक्ट पास होने के लिए नहीं / कोई सिंगलटन आवश्यक नहीं),
  • इनकैप्सुलेटेड बिल्ट-इन प्रकारों का उपयोग करता है और जैसा दिखता है (है) एक विधि कॉल है App,
  • अलग-अलग कॉन्फिग अपरिवर्तनीयता पर नियंत्रण है , म्यूटेबल ग्लोबल्स सबसे खराब प्रकार के ग्लोबल्स हैं
  • अपने स्रोत कोड में पारंपरिक और अच्छी तरह से नामित पहुंच / पठनीयता को बढ़ावा देता है
  • एक साधारण वर्ग है लेकिन संरचित पहुंच को लागू करता है , एक विकल्प का उपयोग करना है @property, लेकिन इसके लिए प्रति आइटम अधिक चर हैंडलिंग कोड की आवश्यकता होती है और ऑब्जेक्ट-आधारित है।
  • नए कॉन्फिगर आइटम को जोड़ने और उसकी उत्परिवर्तन को सेट करने के लिए न्यूनतम परिवर्तनों की आवश्यकता होती है

--Edit-- : बड़े अनुप्रयोगों के लिए, एक YAML (यानी गुण) फ़ाइल में मानों को संचय करना और यह पढ़ना कि अपरिवर्तनीय डेटा के रूप में एक बेहतर तरीका है (यानी ब्लब / ऑहल का उत्तर )। छोटे अनुप्रयोगों के लिए, ऊपर का यह समाधान सरल है।


9

कक्षाओं का उपयोग करने के बारे में कैसे?

# config.py
class MYSQL:
    PORT = 3306
    DATABASE = 'mydb'
    DATABASE_TABLES = ['tb_users', 'tb_groups']

# main.py
from config import MYSQL

print(MYSQL.PORT) # 3306

8

ब्लूब के जवाब के समान। मैं उन्हें कोड को कम करने के लिए लंबो कार्यों के साथ निर्माण करने का सुझाव देता हूं। ऐशे ही:

User = lambda passwd, hair, name: {'password':passwd, 'hair':hair, 'name':name}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3']['password']  #> password
config['blubb']['hair']      #> black

यह गंध करता है जैसे आप एक वर्ग बनाना चाहते हैं, हालांकि।

या, जैसा कि मार्कएम ने कहा, आप उपयोग कर सकते हैं namedtuple

from collections import namedtuple
#...

User = namedtuple('User', ['password', 'hair', 'name']}

#Col      Username       Password      Hair Color  Real Name
config = {'st3v3' : User('password',   'blonde',   'Steve Booker'),
          'blubb' : User('12345678',   'black',    'Bubb Ohaal'),
          'suprM' : User('kryptonite', 'black',    'Clark Kent'),
          #...
         }
#...

config['st3v3'].password   #> passwd
config['blubb'].hair       #> black

3
passएक दुर्भाग्यपूर्ण चर नाम है, क्योंकि यह भी एक खोजशब्द है।
थॉमस श्रेटर

ओह, हाँ ... मैं सिर्फ एक साथ इस गूंगा उदाहरण खींच लिया। मैं नाम
बदलूंगा

इस तरह के दृष्टिकोण के लिए, आप mkDictलैम्ब्डा के बजाय एक वर्ग पर विचार कर सकते हैं । यदि हम अपनी कक्षा को कहते हैं User, तो आपकी "कॉन्फिगरेशन" डिक्शनरी कीज़ को इनिशियलाइज़ किया जाएगा {'st3v3': User('password','blonde','Steve Booker')}। जब आपका "उपयोगकर्ता" एक userचर में होता है, तो आप इसके गुणों को इस प्रकार एक्सेस कर सकते हैं user.hair, आदि
एंड्रयू पामर

यदि आप इस शैली को पसंद करते हैं, तो आप संग्रह का उपयोग करने का विकल्प भी चुन सकते हैं । User = namedtuple('User', 'passwd hair name'); config = {'st3v3': User('password', 'blonde', 'Steve Booker')}
मार्कएम

7

हस्की के विचार पर एक छोटा बदलाव जो मैं उपयोग करता हूं। एक फाइल बनाएं जिसे 'ग्लोबल्स' (या जो कुछ भी आपको पसंद है) और फिर उसमें कई कक्षाएं परिभाषित करें, जैसे:

#globals.py

class dbinfo :      # for database globals
    username = 'abcd'
    password = 'xyz'

class runtime :
    debug = False
    output = 'stdio'

फिर, यदि आपके पास दो कोड फाइलें c1.py और c2.py हैं, तो दोनों शीर्ष पर हो सकते हैं

import globals as gl

अब सभी कोड मानों को एक्सेस और सेट कर सकते हैं, जैसे:

gl.runtime.debug = False
print(gl.dbinfo.username)

लोग कक्षाओं को भूल जाते हैं, भले ही कोई वस्तु कभी भी तात्कालिक न हो, जो उस वर्ग का सदस्य हो। और एक वर्ग में चर जो 'स्व' से पहले नहीं हैं। वर्ग के सभी उदाहरणों में साझा किए जाते हैं, भले ही कोई भी हो। किसी भी कोड द्वारा एक बार 'डिबग' बदल दिए जाने के बाद, अन्य सभी कोड परिवर्तन को देखते हैं।

इसे gl के रूप में आयात करके, आपके पास कई ऐसी फ़ाइलें और चर हो सकते हैं, जो आपको कोड फ़ाइलों, फ़ंक्शंस आदि में मानों को एक्सेस करने और सेट करने की सुविधा देते हैं, लेकिन नाम स्थान के टकराव का कोई खतरा नहीं है।

इसके पास अन्य दृष्टिकोणों की कुछ चतुर त्रुटि की कमी है, लेकिन सरल और अनुसरण करना आसान है।


1
यह एक मॉड्यूल का नाम देने के लिए गलत है globals, क्योंकि यह एक अंतर्निहित फ़ंक्शन है जो वर्तमान वैश्विक दायरे में हर प्रतीक के साथ एक तानाशाही देता है। इसके अलावा, PEP8 वर्ग (यानी DBInfo) के लिए CamelCase (सभी राजधानियों में) के साथ तथाकथित कॉन्स्टेंट (यानी ) के लिए अंडरस्कोर के साथ अपरकेस की सिफारिश करता है DEBUG
नूनो एंड्रे

1
धन्यवाद @ NunoAndré टिप्पणी के लिए, जब तक मैं इसे पढ़ता हूं मैं सोच रहा था कि यह उत्तर कुछ अजीब करता है globals, लेखक नाम बदल देगा
oglop

यह दृष्टिकोण मेरा जाना है। मैं हालांकि बहुत सारे दृष्टिकोण देखता हूं जो लोग कहते हैं कि "सबसे अच्छा" है। क्या आप config.py को लागू करने के लिए कुछ कमियों को बता सकते हैं?
यश नाग

5

चलो ईमानदार होना चाहिए, हमें शायद एक पायथन सॉफ्टवेयर फाउंडेशन पुस्तकालय बनाए रखने पर विचार करना चाहिए :

https://docs.python.org/3/library/configparser.html

विन्यास उदाहरण: (आईएनआई प्रारूप, लेकिन JSON उपलब्ध)

[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes

[bitbucket.org]
User = hg

[topsecret.server.com]
Port = 50022
ForwardX11 = no

कोड उदाहरण:

>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.read('example.ini')
>>> config['DEFAULT']['Compression']
'yes'
>>> config['DEFAULT'].getboolean('MyCompression', fallback=True) # get_or_else

इसे विश्व स्तर पर सुलभ बनाना:

import configpaser
class App:
 __conf = None

 @staticmethod
 def config():
  if App.__conf is None:  # Read only once, lazy.
   App.__conf = configparser.ConfigParser()
   App.__conf.read('example.ini')
  return App.__conf

if __name__ == '__main__':
 App.config()['DEFAULT']['MYSQL_PORT']
 # or, better:
 App.config().get(section='DEFAULT', option='MYSQL_PORT', fallback=3306)
 ....

downsides:

  • अनियंत्रित वैश्विक उत्परिवर्तन राज्य।

यदि आप कॉन्फ़िगरेशन को बदलने के लिए अपनी अन्य फ़ाइलों में स्टेटमेंट्स लागू करना चाहते हैं तो .ini फ़ाइल का उपयोग करना उपयोगी नहीं है। इसके बजाय config.py का उपयोग करना बेहतर होगा, लेकिन यदि मान नहीं बदलते हैं, और आप इसे कॉल और उपयोग करते हैं, तो मैं .ii फ़ाइल के उपयोग से सहमत हूं।
कुरोश

3

कृपया IPython कॉन्फ़िगरेशन सिस्टम की जाँच करें, जिस प्रकार के प्रवर्तन के माध्यम से आपके द्वारा मैन्युअल रूप से किए जा रहे हैं।

समय के साथ लिंक की सामग्री के रूप में लिंक नहीं छोड़ने के लिए SO दिशानिर्देशों का पालन करने के लिए कट और पेस्ट किया गया है।

विशेषता दस्तावेज

यहाँ मुख्य आवश्यकताएं हैं जो हम चाहते थे कि हमारी विन्यास प्रणाली निम्नलिखित है:

पदानुक्रमित कॉन्फ़िगरेशन जानकारी के लिए समर्थन।

कमांड लाइन विकल्प पार्सर के साथ पूर्ण एकीकरण। अक्सर, आप एक कॉन्फ़िगरेशन फ़ाइल पढ़ना चाहते हैं, लेकिन फिर कमांड लाइन विकल्पों के साथ कुछ मानों को ओवरराइड करते हैं। हमारा कॉन्फ़िगरेशन सिस्टम इस प्रक्रिया को स्वचालित करता है और प्रत्येक कमांड लाइन विकल्प को कॉन्फ़िगरेशन पदानुक्रम में एक विशेष विशेषता से जुड़ा होने की अनुमति देता है जो इसे ओवरराइड करेगा।

कॉन्फ़िगरेशन फ़ाइलें जो स्वयं मान्य पायथन कोड हैं। यह कई चीजों को पूरा करता है। सबसे पहले, आपकी कॉन्फ़िगरेशन फ़ाइलों में तर्क डालना संभव हो जाता है, जो आपके ऑपरेटिंग सिस्टम, नेटवर्क सेटअप, पायथन संस्करण, आदि के आधार पर विशेषताएँ सेट करता है। दूसरा, पायथन में पदानुक्रमित डेटा संरचनाओं को एक्सेस करने के लिए एक सुपर सिंपल सिंटैक्स होता है, जिसका मतलब है नियमित विशेषता एक्सेस (फू)। Bar.Bam.name)। तीसरा, पायथन का उपयोग करना उपयोगकर्ताओं के लिए कॉन्फ़िगरेशन विशेषताओं को एक कॉन्फ़िगरेशन फ़ाइल से दूसरे में आयात करना आसान बनाता है। चौथा, भले ही पायथन गतिशील रूप से टाइप किया गया हो, इसमें ऐसे प्रकार होते हैं जिन्हें रनटाइम पर चेक किया जा सकता है। इस प्रकार, एक विन्यास फाइल में 1 पूर्णांक '1' है, जबकि '1' एक स्ट्रिंग है।

कक्षाओं के लिए कॉन्फ़िगरेशन जानकारी प्राप्त करने के लिए एक पूरी तरह से स्वचालित विधि जो इसे रनटाइम पर चाहिए। एक विशेष गुण निकालने के लिए कॉन्फ़िगरेशन पदानुक्रम को चलाने वाला कोड लिखना दर्दनाक है। जब आपके पास सैकड़ों विशेषताओं के साथ जटिल कॉन्फ़िगरेशन जानकारी होती है, तो यह आपको रोना चाहता है।

प्रकार की जाँच और मान्यता जो रनटाइम से पहले पूरे विन्यास पदानुक्रम को वैधानिक रूप से निर्दिष्ट करने की आवश्यकता नहीं है। पायथन एक बहुत ही गतिशील भाषा है और आप हमेशा एक कार्यक्रम शुरू होने पर सब कुछ नहीं जानते हैं जिसे कॉन्फ़िगर करने की आवश्यकता है।

इसे स्वीकार करने के लिए वे मूल रूप से 3 ऑब्जेक्ट क्लास और उनके संबंधों को एक दूसरे से परिभाषित करते हैं:

1) विन्यास - मूल रूप से विलय के लिए कुछ संवर्द्धन के साथ मूल रूप से एक चेनपॉइंट / मूल ताना।

2) कॉन्फ़िगर करने योग्य - बेस क्लास उन सभी चीजों को उपवर्गित करने के लिए जिन्हें आप कॉन्फ़िगर करना चाहते हैं।

3) अनुप्रयोग - एक विशिष्ट एप्लिकेशन फ़ंक्शन या एकल उद्देश्य सॉफ़्टवेयर के लिए आपका मुख्य अनुप्रयोग करने के लिए त्वरित किया गया ऑब्जेक्ट।

उनके शब्दों में:

आवेदन: आवेदन

एक आवेदन एक प्रक्रिया है जो एक विशिष्ट कार्य करती है। सबसे स्पष्ट अनुप्रयोग ipython कमांड लाइन प्रोग्राम है। प्रत्येक एप्लिकेशन एक या अधिक कॉन्फ़िगरेशन फ़ाइलों और कमांड लाइन विकल्पों का एक सेट पढ़ता है और फिर एप्लिकेशन के लिए एक मास्टर कॉन्फ़िगरेशन ऑब्जेक्ट बनाता है। यह कॉन्फ़िगरेशन ऑब्जेक्ट तब कॉन्फ़िगर करने योग्य ऑब्जेक्ट्स के पास जाता है जो एप्लिकेशन बनाता है। ये कॉन्फ़िगर करने योग्य ऑब्जेक्ट एप्लिकेशन के वास्तविक तर्क को लागू करते हैं और जानते हैं कि कॉन्फ़िगरेशन ऑब्जेक्ट को देखते हुए खुद को कैसे कॉन्फ़िगर किया जाए।

एप्लिकेशन में हमेशा एक लॉग एट्रिब्यूट होता है जो एक कॉन्फ़िगर किया हुआ लॉगर होता है। यह प्रति एप्लिकेशन केंद्रीकृत लॉगिंग कॉन्फ़िगरेशन की अनुमति देता है। विन्यास: विन्यास

एक विन्यास योग्य पायथन वर्ग है जो एक अनुप्रयोग में सभी मुख्य वर्गों के लिए आधार वर्ग के रूप में कार्य करता है। विन्यास योग्य बेस क्लास हल्का है और केवल एक ही चीज़ करता है।

यह कॉन्फ़िगर करने योग्य हैसट्रेट्स का एक उपवर्ग है जो अपने आप को कॉन्फ़िगर करना जानता है। मेटाडेटा कॉन्फिगरेशन के साथ क्लास लेवल ट्रेस = ट्रू मान बन जाता है जिसे कमांड लाइन और कॉन्फिगरेशन फाइल्स से कन्फिगर किया जा सकता है।

डेवलपर्स विन्यास योग्य उपवर्ग बनाते हैं जो अनुप्रयोग में सभी तर्क को लागू करते हैं। इन उपवर्गों में से प्रत्येक की अपनी कॉन्फ़िगरेशन जानकारी होती है जो नियंत्रित करती है कि कैसे वृत्तियाँ बनती हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.