2011-01-30 26 views
5

के भीतर भी उपयोग योग्य है, मैं पाइथन में एक विरासत वर्ग के रूप में "उप-संचार" प्रणाली को लागू करने की कोशिश कर रहा हूं।कक्षा में एक सजावट को परिभाषित करना, जो वर्ग परिभाषा

from command import Command 
import sys 

class MyCommand(Command): 
    @Command.subcommand 
    def foo(self): 
     print "this can be run as a subcommand" 

    def bar(self): 
     print "but this is a plain method and isn't exposed to the CLI" 

MyCommand()(*sys.argv) 

# at the command line, the user runs "mycommand.py foo" 

मैं एक स्थिर पद्धति के रूप में Command.subcommand कार्यान्वित किया है और सब कुछ ठीक काम किया जब तक मैं माता पिता के वर्ग है, जो मुझे TypeError: 'staticmethod' object is not callable मिला करने के लिए एक subcommand जोड़ने की कोशिश की: मेरी उम्मीद उपयोग के मामले में कुछ की तरह है। मसा में, यह स्पष्ट है कि this काम नहीं करेगा:

class Command(object): 
    @staticmethod 
    def subcommand(method): 
     method.is_subcommand = True 

     return method 

    @subcommand 
    def common(self): 
     print "this subcommand is available to all child classes" 

एकमात्र विकल्प मैं अब तक मिल गया है माता पिता कक्षा के बाहर subcommand डेकोरेटर घोषित करने के लिए है, तो यह इंजेक्षन के बाद वर्ग परिभाषा पूरा हो गया है है।

def subcommand(method): 
    method.is_subcommand = True 

    return method 

class Command(object): 
    @subcommand 
    def common(self): 
     print "this subcommand is available to all child classes" 

Command.subcommand = staticmethod(subcommand) 
del subcommand 

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

+0

खैर, पहला सवाल यह है कि आप एक सजावट को कक्षा में एक विधि के रूप में क्यों लागू करते हैं, जब तक उस वर्ग का उपयोग सजावट के समूह के लिए नहीं किया जाता है। और यदि यह इसके लिए है, तो आप सजावट को "आम" क्यों सजा रहे हैं? यह संभवतः घबराहट महसूस करता है क्योंकि आपकी कक्षा का डिज़ाइन थोड़ा अजीब है ... :) –

+0

आप इस सजावटकर्ता को आपके लिए क्या उम्मीद कर रहे हैं? पाइथन पहले से ही जानता है कि उपमहाद्वीप क्या हैं, क्योंकि यह जानता है कि कक्षाएं दूसरों के उप-वर्ग हैं। –

+0

@Lennart - शुद्ध रूप से आयात सौंदर्यशास्त्र के लिए। मैं 'आयात कमांड का प्रशंसक नहीं था ... कक्षा MyCommand (कमांड। कमांड)' (अनावश्यक लगता है) या 'कमांड आयात * से ... @ उपसमंद' (नामस्थान को प्रदूषित करने जैसा लगता है)। –

उत्तर

5

इस समस्या के दो समाधान हैं जिन पर मैं सोच सकता हूं। सबसे सरल तो वह एक स्थिर विधि के बाद आप माता-पिता कक्षा में उपयोग समाप्त होते बनाना है:

class Command(object): 
    def subcommand(method): # Regular function in class definition scope. 
     method.is_subcommand = True 

     return method 

    @subcommand 
    def common(self): 
     print "this subcommand is available to all child classes" 

    subcommand = staticmethod(subcommand) 
    # Now a static method. Can no longer be called during class definition phase. 

यह कुछ हद तक कमजोर है कि आप माता-पिता कक्षा में उपयोग नहीं कर सकते ऐसा करने के बाद है एक स्थिर विधि।

class Command(object): 
    @staticmethod 
    def subcommand(method): 
     method.is_subcommand = True 

     return method 

class CommandBase(Command): 

    @Command.subcommand 
    def common(self): 
     print "this subcommand is available to all child classes" 

अब आप CommandBase बजाय Command से अपनी कक्षाओं के सभी वारिस कर सकते हैं: यह करने के लिए और अधिक मजबूत तरीका एक मध्यवर्ती वर्ग को जोड़ने के लिए है।

+0

यह आश्चर्यजनक है। मैंने सोचा होगा कि कक्षा के तरीकों के सजावटी निष्पादकों को निष्पादित करते समय कक्षा स्वयं ही मौजूद नहीं थी (मेटाक्लास को अंत में बुलाया जाता है), लेकिन फिर भी उपमहाद्वीप पाया जाता है। वैसे भी आपके दोनों उदाहरणों में टाइपो हैं: पहले अंत में अनुपलब्ध उद्धरण और शायद आप दूसरे में 'कमांड.subcommand' मतलब था। क्या मैं सही हूँ? – 6502

+0

@ 6502 मैंने टाइपो तय कर दिए हैं। यदि आप पहले उदाहरण में 'सबकॉमैंड' की परिभाषा को देखते हैं, तो आप देखेंगे कि इसे नियमित फ़ंक्शन के रूप में परिभाषित किया गया है। सभी विधि परिभाषाएं उस क्षेत्र में होती हैं जिसमें 'सबकमैंड' पाया जाता है, इसलिए यह उम्मीद की जा सकती है कि उस क्षेत्र में सबकमैंड दिखाई दे रहा है। – aaronasterling

+0

हां यह समझ में आता है ... उपमहाद्वीप कक्षा के शरीर के अंत तक केवल एक स्थानीय चर है, उस बिंदु पर शब्दकोश बनाया गया है और मेटाक्लास को भेजा गया है। फिर भी मुझे अजीब लेखन लगता है उदा।कक्षा के बयान के शरीर में थोड़ी देर लूप :- डी ... – 6502

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