"नई" शैली कक्षाओं का उपयोग करना (मैं अजगर 3.2 में हूं) क्या कई फाइलों पर कक्षा को विभाजित करने का कोई तरीका है? मुझे एक बड़ी कक्षा मिली है (जो वास्तव में एक ऑब्जेक्ट उन्मुख डिजाइन परिप्रेक्ष्य से एक वर्ग होना चाहिए, युग्मन पर विचार करना आदि, लेकिन वर्ग को संपादित करने में आसानी के लिए कुछ फ़ाइलों को विभाजित करना अच्छा होगा।क्या आंशिक कक्षाओं के बराबर कोई पायथन है?
उत्तर
यदि आपकी समस्या वास्तव में एक संपादक में एक बड़ी कक्षा के साथ काम कर रही है, तो पहला समाधान जो मैं वास्तव में देखता हूं वह समस्या को तोड़ने का एक बेहतर तरीका है। दूसरा समाधान एक बेहतर संपादक होगा, अधिमानतः एक कोड फोल्डिंग के साथ।
उस ने कहा, आप कई फाइलों में कक्षा को तोड़ने के कुछ तरीके हैं। पाइथन आपको __init__.py
डालकर मॉड्यूल के रूप में फ़ोल्डर का उपयोग करने देता है, जो तब अन्य फ़ाइलों से चीजें आयात कर सकता है। हम प्रत्येक समाधान में इस क्षमता का उपयोग करेंगे। पहले कहें, bigclass
नामक एक फ़ोल्डर बनाएं।
फ़ोल्डर में विभिन्न
.py
फ़ाइलों है कि अंततः अपने वर्ग शामिल होंगे डाल दिया। प्रत्येक में अंतिम कक्षा, कक्षाओं के लिए कार्य और चर परिभाषाएं होनी चाहिए।__init__.py
में एक ही फ़ोल्डर में सभी को एक साथ जोड़ने के लिए निम्नलिखित लिखें।class Bigclass(object): from classdef1 import foo, bar, baz, quux from classdef2 import thing1, thing2 from classdef3 import magic, moremagic # unfortunately, "from classdefn import *" is an error or warning num = 42 # add more members here if you like
यह लाभ यह है कि आप एक ही वर्ग
object
से ली हुई है, जो आपके विरासत रेखांकन में अच्छा लगेगा के साथ खत्म हो गया है।आप अपनी कक्षा के विभिन्न हिस्सों को गठबंधन करने के लिए एकाधिक विरासत का उपयोग कर सकते हैं। अपने व्यक्तिगत मॉड्यूल में आप कक्षा के कुछ हिस्सों के साथ
Bigclass
के लिए कक्षा परिभाषा लिखेंगे। फिर अपने__init__.py
लिखने में:import classdef1, classdef2, classdef3 class Bigclass(classdef1.Bigclass, classdef2.Bigclass, classdef3.Bigclass): num = 42 # add more members if desired
एकाधिक वंशानुक्रम एक मुद्दा बन जाता है, तो आप कर सकते हैं उपयोग एकल विरासत: सिर्फ श्रृंखला फैशन में एक दूसरे से प्रत्येक वर्ग इनहेरिट की है। मान लीजिए कि आप एक से अधिक कक्षा में कुछ भी परिभाषित नहीं करते हैं, आदेश कोई फर्क नहीं पड़ता।
import classdef1 class Bigclass(classdef1.Bigclass): # more member defs here
classdef3
classdef2
सेBigclass
आयात और इसे करने के लिए जोड़ना होगा, और इतने पर: उदाहरण के लिए,classdef2.py
जैसा होगा। आपका__init__.py
अभी पिछले एक आयात होगा:from classdef42 import Bigclass
मैं आम तौर पर पसंद करते हैं # 1, क्योंकि यह क्या सदस्यों को आप से जो फ़ाइलें लेकिन इन समाधानों में से किसी भी आप के लिए काम कर सकता था आयात कर रहे हैं के बारे में अधिक स्पष्ट है।
मॉड्यूल नाम के रूप में फ़ोल्डर नाम का उपयोग कर इन परिदृश्यों आप इसे आयात कर सकते हैं में से किसी में वर्ग का उपयोग करने के लिए,: from bigclass import Bigclass
+1: मेरे उत्तर के समान ही उतना ही अधिक सुरुचिपूर्ण। – obmarg
+1 मुझे आपके विकल्पों में से पहला सबसे अच्छा अब तक उल्लिखित किसी भी तरह का सबसे अच्छा पसंद है। – wberry
इस उत्तर को समाधान के रूप में चिह्नित करना क्योंकि अन्य उत्तरों सुझाव देते हैं कि * आमतौर पर * एक बड़ी कक्षा वास्तव में एक वर्ग नहीं होनी चाहिए। लेकिन मैं यह मानता हूं कि वे मौलिक रूप से होते हैं और यह उत्तर स्थिति से निपटने के लिए कुछ व्यावहारिक तरीकों की पेशकश करता है। –
मैं इसे इस्तेमाल नहीं किया है, लेकिन this package called partial दावों आंशिक वर्गों के लिए समर्थन जोड़ने के लिए।
ऐसा लगता है जैसे कुछ अन्य तरीके आप स्वयं इस रूप में अच्छी तरह लागू कर सकता है।
आप के अलग अलग हिस्सों को लागू कर सकता है अलग फ़ाइलों में मिश्रित के रूप में कक्षा, फिर उन्हें कहीं भी आयात करें और उन्हें उपclass।
परिवर्तन मूल रूप से, आप किसी केंद्रीय फ़ाइल में कहीं भी अपनी कक्षा के प्रत्येक तरीके को कार्यान्वित कर सकते हैं और उन्हें ऑब्जेक्ट आयात करने के लिए उन्हें कक्षा में विशेषताओं के रूप में असाइन कर सकते हैं। इसलिए जैसा:
a.py:
def AFunc(self, something):
# Do something
pass
b.py:
def BFunc(self, something):
# Do something else
pass
c.py:
import a, b
class C:
AFunc = a.AFunc
BFunc = b.BFunc
तुम भी अब तक इस स्वचालित करने के लिए के रूप में जा सकते हैं यदि आप वास्तव में चाहते थे तो प्रक्रिया - मॉड्यूल a
और b
द्वारा प्रदान किए गए सभी कार्यों के माध्यम से लूप करें और फिर जोड़ें C
पर विशेषताओं के रूप में एम। हालांकि यह कुल ओवरकिल हो सकता है।
इसके बारे में जाने के लिए अन्य (संभवतः बेहतर) तरीके हो सकते हैं, लेकिन वे 2 हैं जो दिमाग में चले गए हैं।
सैकड़ों लाइनों वाली कक्षा परिभाषाएं "जंगली में" होती हैं (मैंने कुछ लोकप्रिय ओपन-सोर्स पायथन-आधारित ढांचे में देखा है), लेकिन मेरा मानना है कि यदि आप सोचते हैं कि विधियां क्या कर रही हैं, तो यह संभव होगा एक प्रबंधन बिंदु पर अधिकांश कक्षाओं की लंबाई को कम करने के लिए। कुछ उदाहरण:
- उन स्थानों की तलाश करें जहां अधिकतर कोड एक से अधिक बार होते हैं। उस कोड को अपनी विधि में तोड़ दें और इसे तर्क के साथ प्रत्येक स्थान से कॉल करें।
- "निजी" विधियां जो किसी ऑब्जेक्ट स्टेट का उपयोग नहीं करती हैं, उन्हें कक्षा से बाहर अकेले कार्यों के रूप में लाया जा सकता है।
- विधियों जिन्हें केवल कुछ शर्तों के तहत बुलाया जाना चाहिए, उन तरीकों को उप-वर्ग में रखने की आवश्यकता को इंगित कर सकते हैं।
सीधे आपके प्रश्न को हल करने के लिए, यह एक वर्ग की परिभाषा को विभाजित करने के लिए संभव है। एक तरीका यह है कि इसे "बंदर-पैच" वर्ग को परिभाषित करके और उसके बाद बाहरी कार्यों को विधियों के रूप में जोड़ना है। दूसरा एक "हाथ से" वर्ग बनाने के लिए अंतर्निहित type
फ़ंक्शन का उपयोग करना है, इसका नाम, किसी भी बेस क्लास, और इसकी विधियों और विशेषताओं को एक शब्दकोश में आपूर्ति करना है। लेकिन मैं ऐसा करने की सिफारिश नहीं करता क्योंकि परिभाषा अन्यथा लंबी होगी। इस तरह की इलाज मेरी राय में बीमारी से भी बदतर है।
+1: आईएमएचओ, यह बहुत समझदार सलाह है। –
मैं मानता हूं कि आम तौर पर एक बड़ी कक्षा से पता चलता है कि इसे एक से अधिक ज़िम्मेदारी मिली है और नहीं चाहिए।हालांकि, वे होते हैं (यहां तक कि सर्वोत्तम प्रथाओं का पालन भी)। –
वास्तव में वे करते हैं। मैंने हाल ही में तर्कसंगत अंकगणितीय के लिए लिखा है कि 362 लाइनें हैं, जिनमें लंबे डॉकस्ट्रिंग शामिल हैं, सभी खाली लाइनें छीन ली गई हैं। हालांकि मेरे पास '_' से शुरू होने वाले नामों के साथ कुछ '@ staticmethod' है, जो मेरी अपनी सलाह से शायद कार्यों के रूप में बाहर ले जाया जाना चाहिए। इससे लंबाई लगभग आधा हो जाएगी। – wberry
सबसे पहले मैं यह कहना चाहता हूं कि यह जटिल है कि यह संभवतः क्लास में अपना स्थान ढूंढने के लिए एक अच्छा विचार नहीं है - टिप्पणियां जोड़ने, अनुभागों को हाइलाइट करना सबसे अच्छा होगा।
कई फ़ाइलों में वर्ग लिखें उन्हें पाठ के रूप में पढ़ा तो, उन्हें और
exec
जिसके परिणामस्वरूप स्ट्रिंग श्रेणीबद्ध: हालांकि, मैं दो तरीकों से ऐसा कर सकता है देखते हैं।प्रत्येक फ़ाइल में एक अलग वर्ग बनाएं, फिर उन्हें सभी को मास्टर श्रेणी में मिश्रित के रूप में प्राप्त करें। हालांकि, अगर आप पहले से ही किसी अन्य वर्ग को उप-वर्गीकृत कर रहे हैं तो इससे एमआरओ समस्याएं हो सकती हैं। आप अपने मास्टर क्लास के लिए मेटाक्लास बनाकर इसे प्राप्त कर सकते हैं जो मैन्युअल रूप से एमआरओ को हल करता है, लेकिन यह गन्दा हो सकता है।
सबसे आसान विकल्प पहला विकल्प होगा।
मैं पहले कुछ इसी तरह के साथ चारों ओर toyed है। मेरा उपयोगकेस एक अमूर्त वाक्यविन्यास पेड़ में नोड्स का एक वर्ग पदानुक्रम था, और फिर मैं सभी उदा। prettyprinting फ़ंक्शंस एक अलग prettyprint.py फ़ाइल में है लेकिन अभी भी उन्हें कक्षाओं में विधियों के रूप में है।
एक चीज जिसकी मैंने कोशिश की थी वह एक सजावट का उपयोग करना था जो सजाए गए कार्य को निर्दिष्ट कक्षा पर एक विशेषता के रूप में रखता था। मेरे मामले में इसका मतलब यह होगा कि prettyprint.py अलग @inclass(...)
इस के साथ एक समस्या यह है कि एक यकीन है कि उप फ़ाइलें हमेशा आयात किए जाते हैं बनाना चाहिए है के साथ सजाया def prettyprint(self)
सभी के बहुत सारे शामिल है, और है कि वे मुख्य वर्ग पर निर्भर करते हैं, जो एक परिपत्र निर्भरता के लिए बनाता है, जो गन्दा हो सकता है।
def inclass(kls):
"""
Decorator that adds the decorated function
as a method in specified class
"""
def _(func):
setattr(kls,func.__name__, func)
return func
return _
## exampe usage
class C:
def __init__(self, d):
self.d = d
# this would be in a separate file.
@inclass(C)
def meth(self, a):
"""Some method"""
print "attribute: %s - argument: %s" % (self.d, a)
i = C(10)
print i.meth.__doc__
i.meth(20)
वाह, विधियों के लिए एक भेजने के लिए! – wberry
सबसे पहले, मुझे नहीं लगता कि कक्षा को कई फाइलों में विभाजित करने से कोई संपादन आसान हो जाता है। एक सभ्य आईडीई किसी भी विधि को आसानी से ढूंढने में सक्षम होना चाहिए चाहे एक फ़ाइल या एकाधिक में; यदि आप एक सभ्य आईडीई का उपयोग नहीं कर रहे हैं, तो क्लास को विभाजित करने का अर्थ है कि रखरखावकर्ता को अनुमान लगाया जाना चाहिए कि कौन सी फ़ाइल दी गई विधि है, जो आसान के बजाय कठिन लगती है।
अधिक मौलिक रूप से, यह वर्ग - इतना बड़ा है कि आप अपने वजन का समर्थन करने के लिए एक विशेष भाषा सुविधा चाहते हैं - मूल रूप से टूटा हुआ लगता है। हम किस कोड की बात कर रहे हैं? लगभग निश्चित रूप से, यह एक करने के लिए एक बेहतर विचार होगा:
- Refactor कम, अधिक सामान्य पुरातन में कोड दोहराया
- एक आधार वर्ग परिभाषित करें और उपवर्गों के साथ विस्तार के रूप में कारोले होर्वाथ टिप्पणी में पता चलता है (यह है 'आंशिक कक्षाओं' की सबसे नज़दीकी चीज जिसे आप पूछ रहे हैं, मैं समर्थन दूंगा)
- इस वर्ग की कार्यक्षमता के विभिन्न हिस्सों को समाहित करने के लिए कुछ अलग वर्गों को परिभाषित करें, और छोटे के उदाहरणों के इस वर्ग को लिखें।
मैं एक ही स्थिति से मिला - मैं अपनी कक्षा को 2 फाइलों में फिसलना चाहता हूं। कारण यह है कि - मुझे जीयूआई लेआउट के लिए भाग 1 चाहिए, केवल लेआउट और दूसरी फ़ाइल सभी फ़ंक्शन रखती है। सी # के आंशिक वर्ग की तरह। एक्सएएमएल के लिए एक और कार्यों के लिए एक और।
तुम इतनी तरह सज्जाकार के साथ ऐसा कर सकते हैं:
class Car(object):
def start(self):
print 'Car has started'
def extends(klass):
def decorator(func):
setattr(klass, func.__name__, func)
return func
return decorator
#this can go in a different module/file
@extends(Car)
def do_start(self):
self.start()
#so can this
car = Car()
car.do_start()
#=> Car has started
- 1. आंशिक कक्षाओं का उद्देश्य क्या है?
- 2. आंशिक कक्षाओं का उपयोग
- 3. क्या 'पायदान' के बराबर एक पायथन है
- 4. पायथन में 'मणि' के बराबर क्या है?
- 5. क्या स्कैला में नियमित कक्षाओं के कक्षाओं के मामले में कोई समय या स्थान ओवरहेड है?
- 6. पासपोर्ट.जेएस पायथन के बराबर है?
- 7. क्या कोई जावा libevent के बराबर है?
- 8. क्या कोई PHP sqlite3_limit के बराबर है?
- 9. क्या कोई PHP कम्पास के बराबर है?
- 10. क्या कोई आईआईएस टॉमकैट के बराबर है?
- 11. सी # आंशिक कक्षाओं के साथ त्रुटि
- 12. जनरेटेड आंशिक कक्षाओं के लिए डेटाअनोटेशन जोड़ना
- 13. क्या कोई पाइथन `perl -pi -e` के बराबर है?
- 14. सी ++ पायथन के सिद्धांतों के बराबर है?
- 15. क्या कोई जावास्क्रिप्ट पाइथन की __getattr__ विधि के बराबर है?
- 16. पायथन के नुकीले में "ज़िप()" के बराबर क्या है?
- 17. जाओ - पायथन के "पास" के बराबर क्या है?
- 18. PHP पायथन के समकक्ष() के बराबर है?
- 19. उत्पन्न आंशिक कक्षाओं पर XmlIgnore का उपयोग
- 20. डब्ल्यूसीएफ डेटा सेवा, इकाई फ्रेमवर्क आंशिक कक्षाओं
- 21. क्या कोई XML टैग है जो 'ListView.addHeaderView' के बराबर है?
- 22. सी ++ कक्षाओं के स्वचालित पंपलिंग - क्या कोई आसान तरीका है?
- 23. क्या एसबीसीएल के रन-प्रोग्राम के बराबर कोई योजना है?
- 24. क्या कोई जावा PHP के http_build_query फ़ंक्शन के बराबर है?
- 25. पायथन subprocess Popen.communicate() Popen.stdout.read() के बराबर है?
- 26. पायथन 3.2 में हेक्सडिजिस्ट के बराबर सी # समतुल्य क्या है?
- 27. क्या यह पायथन में एक कॉपी कन्स्ट्रक्टर के बराबर है?
- 28. सी ++ पायथन लेन() फ़ंक्शन के बराबर है?
- 29. java.util.Arrays में बराबर() के रनटाइम क्या है?
- 30. पायथन के बराबर "perl -V"
आप एक आधार वर्ग में कुछ मुख्य कार्यक्षमता रख सकते हैं? –
वाक्यांश "बड़ी कक्षा" और "ऑब्जेक्ट उन्मुख डिजाइन परिप्रेक्ष्य से एकल वर्ग" एक साथ बहुत अच्छी तरह से नहीं जाते हैं। –
@ निकलास, इस बात पर सहमत हुए कि वे आम तौर पर कभी-कभी नहीं करते हैं। मेरी अधिकांश कक्षाएं बहुत छोटी हैं। –