2009-07-13 14 views
7

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

उपयोगकर्ता श्रेणी में कुछ विधियां हैं जो उपयोगकर्ता ऑब्जेक्ट को वापस लाती हैं। जब मैं subclass करता हूं, यह काम नहीं करेगा, क्योंकि मैं एक अपरिवर्तनीय उपयोगकर्ता को एक उपयोगकर्ता को वापस कर दूंगा, जिससे मुझे अन्य तरीकों के साथ इस विधि को कॉल करने से रोक दिया जा सकेगा। हालांकि UnapprovedUser में get() विधि एक UnapprovedUser वस्तु, न कि एक उपयोगकर्ता वापस जाने के लिए की जरूरत है

class User(object): 
    base_dn = 'ou=Users,dc=example,dc=org' 

    @classmethod 
    def get(cls, uid): 
     ldap_data = LdapUtil.get(uid + ',' + self.base_dn) 
     return User._from_ldap(ldap_data) 

class UnapprovedUser(User): 
    base_dn = 'ou=UnapprovedUsers,dc=example,dc=org' 

    def approve(self): 
     new_dn = '' # the new DN 
     LdapUtil.move(self.dn, new_dn) 

get() और _from_ldap() तरीकों, दोनों वर्गों के लिए ही हैं।

मैं उपयोगकर्ता के उन उदाहरणों में से एक कैसे डाल सकता हूं जो मुझे User.get() से एक अनुमोदित उपयोगकर्ता में मिलता है?

class UnapprovedUser(User): 
    # continued from before 

    @classmethod 
    def get(cls, uid): 
     user = super(UnapprovedUser, cls).get(uid) 
     return (UnapprovedUser) user # invalid syntax 

ताकि मैं माता पिता से विधि लपेट सकते हैं और बस सही वर्ग के लिए दिए गए मान डाली:

मैं की तरह कुछ करना चाहते हैं। फिर फिर, ऐसा करने से माता-पिता को उनके मूल्य का उपयोग self.base_dn के लिए कर सकता है, जो सबकुछ तोड़ देगा।

उत्तर

7

"कास्टिंग" की बजाय, मुझे लगता है कि UnapprovedUser.get() का आह्वान करते समय User की बजाय आप वास्तव में UnapprovedUser बनाना चाहते हैं।

@classmethod 
def get(cls, uid): 
    ldap_data = LdapUtil.get(uid + ',' + self.base_dn) 
    return cls._from_ldap(ldap_data) 

आप _from_ldap में कुछ इसी तरह करने की आवश्यकता होगी:

बदलें User.get वास्तव में cls तर्क है कि पारित कर दिया-इन का उपयोग करने के लिए: ऐसा करने के लिए। आप _from_ldap के लिए कोड श्रेणी में नहीं रखा है, लेकिन मुझे लगता है कि कुछ बिंदु पर यह कुछ ऐसा करता है मान लेते हैं: याद रखें

result = cls(... blah ...) 

:

result = User(... blah ...) 

आप के साथ इस बदलना चाहते हैं अजगर एक वर्ग वस्तु में एक कॉल करने योग्य है जो उस वर्ग के उदाहरण बनाता है। तो आप classmethod को कॉल करने के लिए उपयोग की जाने वाली कक्षा के उदाहरण बनाने के लिए क्लासमेड के cls पैरामीटर का उपयोग कर सकते हैं।

+0

बिल्कुल वही जो मैं खोज रहा था। धन्यवाद। मुझे लगता है मैंने कभी नहीं देखा कि आप क्लास पैरामीटर के साथ क्लास विधि में ऐसा कर सकते हैं। –

2

पायथन एक गतिशील रूप से टाइप की गई भाषा है, इसलिए "कास्टिंग" की अवधारणा मौजूद नहीं है। यदि ऑब्जेक्ट पहले से ही UnapprovedUser है, तो आप उस वर्ग में मौजूद सभी विधियों को पहले से ही कॉल किए बिना कॉल कर सकते हैं।

+2

समस्या यह है कि मैं एक उपयोगकर्ता मेरे लिए लौट आए हो रही है, लेकिन मैं इतना है कि मुझे लगता है कि मीटर कॉल कर सकते हैं यह एक UnapprovedUser होने की जरूरत है ethod। अगर मुझे ऐसा करने की ज़रूरत नहीं है तो मैं कोड डुप्लिकेट नहीं करना चाहता हूं। –

+4

"कास्टिंग" एक संदिग्ध शब्द का थोड़ा सा है (इसलिए सी ++ में विभिन्न प्रकार के कास्ट), लेकिन निश्चित रूप से पाइथन में कम से कम एक प्रकार का कास्टिंग जैसा होता है: प्रकार रूपांतरण। उदाहरण: मैं किसी को यह कहने की कल्पना कर सकता हूं कि str (x) "x" को एक str में "casts" x (हालांकि मुझे लगता है कि ज्यादातर लोग "casts" के बजाय अधिक स्पष्ट "रूपांतरित" के लिए जाते हैं)। –

0

कक्षा विधि में, कक्षा को क्लैस पैरामीटर में पास किया जाता है। तो User.something के बजाय cls.something करते हैं। किया हुआ!

उसने कहा, मुझे यकीन नहीं है कि मैं इसे दो प्रकार के उपयोगकर्ता के साथ करूँगा। मुझे 100% यकीन नहीं है कि यहां "स्वीकृत" के साथ आपका क्या मतलब है, मुझे लगता है कि मुझे दो चीजों में से एक माना जाता है।

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

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

यदि आप अनुमोदित के साथ कुछ और मतलब है, तो इसे अनदेखा करने के लिए स्वतंत्र महसूस करें। :-)

+0

मेरे पास एक साधारण एलडीएपी निर्देशिका संरचना है जिसे मैं उपयोगकर्ताओं को स्टोर करने जा रहा हूं। Ou = उपयोगकर्ता 'स्वीकृत' उपयोगकर्ताओं द्वारा उपयोग किया जाता है। लॉगिन जानकारी के लिए निर्देशिका को देखने वाले अनुप्रयोग केवल ou = उपयोगकर्ता में देखते हैं। मेरे पास उपयोगकर्ता के लिए इन अनुप्रयोगों तक पहुंच का अनुरोध करने का एक तरीका है, जहां उन्हें लॉग इन करने से पहले व्यवस्थापक से अनुमोदन की आवश्यकता होती है। इस मामले में, वे ou = अस्वीकृत उपयोगकर्ता में बनाए जाते हैं, और ou = उपयोगकर्ता का उपयोग करते हुए 'स्वीकृति()' विधि। तो, कोई अतिरिक्त स्तर की आवश्यकता नहीं होगी। –

+0

ठीक है, तो सिद्धांत समझ में आता है। (हालांकि, मानक उपयोगकर्ता पर स्वीकृति विधि होने से चोट नहीं पहुंची है, इसलिए आपको दो अलग-अलग कक्षाओं की आवश्यकता नहीं हो सकती है)। –

1
  • सुपर (UnapprovedUser, आत्म) गलत है यह सुपर होना चाहिए (UnapprovedUser, सीएलएस) क्योंकि वर्ग विधि में आप आधार में, उपलब्ध स्वयं

  • मैं अपने प्रश्न दोहराना होगा की जरूरत नहीं है कक्षा आप उपयोगकर्ता बना रहे हैं और किसी भी तरह से आप व्युत्पन्न कक्षा वापस करना चाहते हैं उदाहरण के लिए


    class User(object): 

     @classmethod 
     def get(cls, uid): 
      return User() 

    class UnapprovedUser(User): 

     @classmethod 
     def get(cls, uid): 
      user = super(UnapprovedUser, cls).get(uid) 
      return user # invalid syntax 

    print UnapprovedUser.get("XXX") 

यह UnapprovedUser वस्तु यहाँ आप UnapprovedUser.get UnapprovedUser वापस जाने के लिए चाहते हैं, उसके लिए आपको एक कारखाने समारोह जो उपयुक्त उपयोगकर्ता लौट wil और की तुलना में यह ldap

से भरना बना सकते हैं के बजाय उपयोगकर्ता वस्तु प्रिंट

    class User(object): 

     @classmethod 
     def get(cls, uid): 
      return cls.getMe() 

     @classmethod 
     def getMe(cls): 
      return cls() 

    class UnapprovedUser(User): 

     @classmethod 
     def get(cls, uid): 
      user = super(UnapprovedUser, cls).get(uid) 
      return user 

    print UnapprovedUser.get("XXX") 

यह UnapprovedUser वस्तु प्रिंट

संबंधित मुद्दे