2009-08-09 10 views
12

मैं पायथन में वर्ग विशेषताओं के बारे में कुछ चर्चा सुनने में दिलचस्पी रखता हूँ। उदाहरण के लिए, वर्ग विशेषताओं के लिए एक अच्छा उपयोग केस क्या है? अधिकांश भाग के लिए, मैं ऐसे मामले के साथ नहीं आ सकता जहां एक वर्ग विशेषता मॉड्यूल स्तर विशेषता का उपयोग करने के लिए बेहतर है। यदि यह सच है, तो उन्हें चारों ओर क्यों है?अजगर कक्षा बनाम मॉड्यूल गुण

समस्या मैं उनके साथ है,

कि यह लगभग भी आसान गलती से एक वर्ग विशेषता मान पीटना करने के लिए, और फिर अपने "वैश्विक" मूल्य एक स्थानीय उदाहरण विशेषता में बदल गया है है।

आप निम्न स्थितियों कैसे संभाल होगा पर टिप्पणी के लिए स्वतंत्र महसूस:

  1. लगातार एक वर्ग और/या उप-वर्गों द्वारा इस्तेमाल किया मूल्यों। इसमें "जादू संख्या" शब्दकोश कुंजी या सूची अनुक्रमणिका शामिल हो सकती हैं जो कभी नहीं बदलेगी, लेकिन संभवतः एक बार प्रारंभिक आवश्यकता की आवश्यकता हो सकती है।
  2. डिफ़ॉल्ट वर्ग विशेषता, दुर्लभ अवसरों में कक्षा के एक विशेष उदाहरण के लिए अद्यतन किया गया।
  3. वैश्विक डेटा संरचना सभी मामलों के बीच साझा की गई कक्षा की आंतरिक स्थिति का प्रतिनिधित्व करने के लिए उपयोग की जाती है।
  4. एक वर्ग कि डिफ़ॉल्ट विशेषताओं का एक नंबर initializes, निर्माता तर्क से प्रभावित नहीं।

कुछ संबंधित पोस्ट:
Difference Between Class and Instance Attributes

+0

समुदाय विकी – SilentGhost

उत्तर

7

# 4: मैं कभी नहीं उपयोग वर्ग डिफ़ॉल्ट उदाहरण जिम्मेदार बताते हैं (जिन्हें आप सामान्य रूप से __init__ में डाल) प्रारंभ करने में जिम्मेदार बताते हैं।

class Obj(object): 
    def __init__(self): 
     self.users = 0 

और कभी नहीं: उदाहरण के लिए:

class Obj(object): 
    users = 0 

क्यों? क्योंकि यह असंगत है:

class Obj(object): 
    users = [] 

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


बाकी के लिए, मैं आमतौर पर कक्षा के अंदर कक्षा-विशिष्ट मूल्य डालता हूं।यह इतना नहीं है क्योंकि ग्लोबल्स "बुराई" हैं - वे कुछ भाषाओं में इतने बड़े सौदे नहीं हैं, क्योंकि वे अभी भी मॉड्यूल में डूब गए हैं, जब तक कि मॉड्यूल स्वयं बहुत बड़ा न हो - लेकिन अगर बाहरी कोड उन्हें एक्सेस करना चाहता है, यह एक ही स्थान पर सभी प्रासंगिक मूल्यों के लिए आसान है। उदाहरण के लिए, module.py में:

class Obj(object): 
    class Exception(Exception): pass 
    ... 

और उसके बाद:

from module import Obj 

try: 
    o = Obj() 
    o.go() 
except o.Exception: 
    print "error" 
एक तरफ उपवर्गों मूल्य (जो हमेशा वैसे भी चाहता था नहीं है) को बदलने के लिए, इसका मतलब है मेरे पास नहीं है की अनुमति देने से

ओबज का उपयोग करने के लिए श्रमिक रूप से अपवाद नाम और अन्य सामानों का एक समूह आयात करने के लिए। "मॉड्यूल आयात ओबीजे, ObjException, ... से" जल्दी थकाऊ हो जाता है।

2

कक्षा विशेषताओं अक्सर उपवर्गों में अधिभावी चूक अनुमति देने के लिए उपयोग किया जाता है। उदाहरण के लिए, BaseHTTPRequestHandler में क्लास स्थिरांक sys_version और server_version है, बाद में "BaseHTTP/" + __version__ पर डिफ़ॉल्ट है। SimpleHTTPRequestHandler सर्वर_वर्जन को "SimpleHTTP/" + __version__ पर ओवरराइड करता है।

+0

होना चाहिए, हालांकि, क्लास विशेषता का एक्सेस तरीका यह काम करेगा या नहीं। एक और कारण क्लास गुण खतरनाक हैं। – cmcginty

+0

क्या "एक्सेस विधि" है? cls.version, self.version, getattr, सभी सही जवाब देंगे। * ओवरराइड की अनुमति देने के लिए कक्षा में परिभाषित करें * कोड के लिए डेटा के लिए भी काम करता है - इसलिए, केसी, आपको लगता है कि यह डेटा के लिए खतरनाक है लेकिन कोड के लिए ठीक है ?! –

+0

विशेषता का उपयोग करने के लिए एक विधि में self.value के बजाय Class.value का उपयोग करके ओवरराइड को होने से रोक देगा।कभी-कभी यह वांछित मामला है, अन्य बार नहीं। – cmcginty

1

इनकैप्सुलेशन एक अच्छा सिद्धांत है: एक विशेषता वर्ग के अंदर है, जब यह बजाय वैश्विक क्षेत्र में होने के से संबंधित है, इस कोड को पढ़ने के लोगों के लिए अतिरिक्त जानकारी देता है।

अपने स्थितियों 1-4 में, मैं इस प्रकार के रूप में ज्यादा के रूप में मैं कर सकते हैं वैश्विक बचने के लिए, और वर्ग जिम्मेदार बताते हैं, जो एक कैप्सूलीकरण से लाभ के लिए अनुमति देते का उपयोग कर पसंद करेंगे।

3

वर्ग के लिए एक अच्छा इस्तेमाल मामला है क्या गुण

प्रकरण 0. कक्षा तरीकों सिर्फ वर्ग विशेषताएँ हैं। यह सिर्फ एक तकनीकी समानता नहीं है - आप उन्हें कॉल करने योग्यों को निर्दिष्ट करके रनटाइम पर कक्षा विधियों तक पहुंच और संशोधित कर सकते हैं।

केस 1. एक मॉड्यूल आसानी से कई कक्षाओं को परिभाषित कर सकता है। class AA... और class B के बारे में सबकुछ B... में सब कुछ encapsulate करना उचित है। उदाहरण के लिए,

# module xxx 
class X: 
    MAX_THREADS = 100 
    ... 

# main program 
from xxx import X 

if nthreads < X.MAX_THREADS: ... 

प्रकरण 2. इस वर्ग डिफ़ॉल्ट गुण जो एक उदाहरण में संशोधित किया जा सकता की बहुत सारी है। यहां 'ग्लोबल डिफॉल्ट' होने के लिए विशेषता छोड़ने की क्षमता एक सुविधा है, बग नहीं।

class NiceDiff: 
    """Formats time difference given in seconds into a form '15 minutes ago'.""" 

    magic = .249 
    pattern = 'in {0}', 'right now', '{0} ago' 

    divisions = 1 

    # there are more default attributes 

एक मौजूदा या थोड़ा संशोधित स्वरूपण का उपयोग करने के NiceDiff के कहने बनाता है, लेकिन एक अलग भाषा के लिए एक localizer एक मौलिक रूप से अलग तरह से कुछ कार्यों को लागू करने वर्ग उपवर्गों और को फिर से परिभाषित स्थिरांक:

class Разница(NiceDiff): # NiceDiff localized to Russian 
    '''Из разницы во времени, типа -300, делает конкретно '5 минут назад'.''' 

    pattern = 'через {0}', 'прям щас', '{0} назад' 

आपका मामलों:

  • स्थिरांक - तु एस, मैं उन्हें कक्षा में डाल दिया। self.CONSTANT = ... कहना अजीब बात है, इसलिए मुझे उन्हें पकड़ने के लिए एक बड़ा जोखिम नहीं दिख रहा है।
  • डिफ़ॉल्ट विशेषता - मिश्रित, ऊपर के रूप में कक्षा में जा सकता है, लेकिन semantics के आधार पर __init__ पर भी जा सकता है।
  • ग्लोबल डेटा स्ट्रक्चर --- क्लास द्वारा केवल का उपयोग करते हुए कक्षा में जाता है, लेकिन मॉड्यूल पर भी जा सकता है, किसी भी मामले में बहुत अच्छी तरह से प्रलेखित होना चाहिए।