क्या MATLAB में प्रति फ़ाइल एक से अधिक फ़ंक्शन को परिभाषित करना संभव है, और उन्हें उस फ़ाइल के बाहर से एक्सेस करना है?


217

जब मैं EE में अपनी स्नातक की डिग्री के लिए अध्ययन कर रहा था, MATLAB को प्रत्येक फ़ंक्शन को अपनी फ़ाइल में परिभाषित करने की आवश्यकता थी, भले ही वह एक-लाइनर हो।

मैं अब स्नातक की डिग्री के लिए अध्ययन कर रहा हूं, और मुझे MATLAB में एक परियोजना लिखना है। क्या यह अभी भी MATLAB के नए संस्करणों के लिए एक आवश्यकता है?

यदि किसी फ़ाइल में एक से अधिक फ़ंक्शन डालना संभव है, तो क्या इसके लिए कोई प्रतिबंध हैं? उदाहरण के लिए, क्या फ़ाइल के सभी कार्यों को फ़ाइल के बाहर से एक्सेस किया जा सकता है, या केवल फ़ंक्शन जो फ़ाइल के समान नाम है?

नोट: मैं MATLAB रिलीज़ R2007b का उपयोग कर रहा हूं।

जवाबों:


271

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

एम-फाइल में सभी बाद के कार्य, जिसे स्थानीय कार्यों (या पुरानी शब्दावली में "सबफंक्शन) कहा जाता है, को केवल उस एम-फाइल में मुख्य फ़ंक्शन और अन्य स्थानीय कार्यों द्वारा बुलाया जा सकता है। अन्य m-files में कार्य उन्हें नहीं कह सकते। R2016b में शुरू, आप स्थानीय कार्यों को स्क्रिप्ट में भी जोड़ सकते हैं , हालांकि स्कूपिंग व्यवहार अभी भी समान है (यानी उन्हें केवल स्क्रिप्ट के भीतर से ही बुलाया जा सकता है)।

इसके अलावा, आप अन्य कार्यों के भीतर कार्यों की घोषणा भी कर सकते हैं । इन्हें नेस्टेड फ़ंक्शन कहा जाता है , और इन्हें केवल फ़ंक्शन के भीतर से बुलाया जा सकता है। वे उन कार्यों में चर तक भी पहुंच सकते हैं जिनमें वे नेस्टेड हैं, जो उनके साथ काम करने के लिए थोड़ा उपयोगी होता है।

विचार के लिए अधिक भोजन ...

ऊपर उल्लिखित सामान्य फ़ंक्शन स्कूपिंग व्यवहार के आस-पास कुछ तरीके हैं, जैसे कि फ़ंक्शन फ़ंक्शन हैंडल आउटपुट के रूप में SCFrench और Jonas (जो R2013b में शुरू होता है, localfunctionsफ़ंक्शन द्वारा सुगम किया गया है) से वर्णित है । हालाँकि, मैं यह सुझाव नहीं दूंगा कि आप इस तरह के ट्रिक का सहारा लें, क्योंकि आपके कार्यों और फाइलों को व्यवस्थित करने के लिए बहुत बेहतर विकल्प हैं।

उदाहरण के लिए, मान लीजिए कि आप एक मुख्य कार्य है चलो Aएक मीटर फ़ाइल में A.m, स्थानीय कार्यों के साथ-साथ D, E, और F। अब मान लीजिए कि आप दो अन्य संबंधित कार्यों जाने Bऔर Cएम-फाइलों में B.mऔर C.mक्रमशः, यह है कि आप भी कॉल करने के लिए सक्षम होना चाहते हैं D, E, और F। आपके पास कुछ विकल्प हैं:

  • रखो D, Eऔर Fप्रत्येक अपनी अलग-अलग एम-फाइलों में, किसी भी अन्य फ़ंक्शन को उन्हें कॉल करने की अनुमति देता है। नकारात्मक पक्ष यह है कि इन कार्यों के दायरे बड़ी है और अभी तक सीमित नहीं होता है A, Bऔर C, लेकिन उल्टा है कि इस काफी सरल है।

  • एक बनाएँ defineMyFunctionsके साथ (जोनास 'उदाहरण की तरह) एम-फ़ाइल D, Eऔर Fस्थानीय कार्य करता है और एक मुख्य समारोह के रूप में कि बस रिटर्न उन्हें हैंडल कार्य करते हैं। यह आपको रखने के लिए अनुमति देता है D, Eऔर, Fएक ही फाइल में है, लेकिन यह किसी भी समारोह है कि कॉल कर सकते हैं के बाद से इन कार्यों के दायरे के बारे में कुछ नहीं करता defineMyFunctionsउन्हें आह्वान कर सकते हैं। फिर आपको यह भी सुनिश्चित करना होगा कि फ़ंक्शन हैंडल को पास करने के लिए तर्क के रूप में यह सुनिश्चित करने के लिए कि आपके पास उनकी ज़रूरत है जहां आपको उनकी आवश्यकता है।

  • कॉपी D, Eऔर Fमें B.mऔर C.mस्थानीय कार्यों के रूप में। यह सीमा केवल करने के लिए उनके उपयोग का दायरा A, B, और C, लेकिन बनाता है अद्यतन करने और अपने कोड एक बुरा सपना के रखरखाव क्योंकि आप अलग अलग स्थानों में एक ही कोड के तीन प्रतियां।

  • निजी कार्यों का उपयोग करें ! यदि आपके पास A, Bऔर Cएक ही निर्देशिका में है, तो आप एक उपनिर्देशिका कहा जाता है बना सकते हैं privateऔर जगह D, Eहै, और Fवहाँ में, एक अलग एम-फ़ाइल के रूप में प्रत्येक। यह उनके कार्यक्षेत्र को सीमित करता है इसलिए वे केवल ठीक उसके ऊपर निर्देशिका में कार्यों के द्वारा कहा जा सकता है (यानी A, Bहै, और C) और उन्हें एक ही स्थान पर एक साथ रहता है (लेकिन अभी भी विभिन्न एम-फ़ाइलें):

    myDirectory/
        A.m
        B.m
        C.m
        private/
            D.m
            E.m
            F.m

यह सब कुछ आपके प्रश्न के दायरे से बाहर चला जाता है, और संभवतः आपकी आवश्यकता से अधिक विवरण है, लेकिन मैंने सोचा कि आपकी सभी एम-फाइलों के आयोजन की अधिक सामान्य चिंता को छूना अच्छा हो सकता है। ;)


3
पसंदीदा उत्तर विकल्प इस तरह दिखता है ^, @idigas
embert

1
@ मुझे लगता है कि वह एक सवाल को आगे बढ़ाने की तर्ज पर था, जो कि स्वतंत्र रूप से फ़ेवरिटिंग के लिए मतदान किया जा सकता है।
OJFord

79

आमतौर पर, आपके प्रश्न का उत्तर नहीं है, आप प्रति फ़ाइल एक से अधिक बाह्य रूप से दिखाई देने वाले फ़ंक्शन को परिभाषित नहीं कर सकते। आप स्थानीय कार्यों के लिए फ़ंक्शन हैंडल वापस कर सकते हैं, हालांकि, और ऐसा करने का एक सुविधाजनक तरीका उन्हें एक संरचना के क्षेत्र बनाना है। यहाँ एक उदाहरण है:

function funs = makefuns
  funs.fun1=@fun1;
  funs.fun2=@fun2;
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

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

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1

36

एक ही फ़ाइल में कई, अलग-अलग सुलभ कार्यों के लिए एकमात्र तरीका ऑब्जेक्ट-उन्मुख प्रोग्रामिंग का उपयोग करके STATIC METHODS को परिभाषित करना है । आप फ़ंक्शन को इस रूप में एक्सेस करेंगे myClass.static1(), myClass.static2()आदि।

OOP कार्यक्षमता केवल R2008a के बाद से आधिकारिक तौर पर समर्थित है, इसलिए जब तक आप पुराने, अनिर्दिष्ट OOP वाक्यविन्यास का उपयोग नहीं करना चाहते हैं, तो आपके लिए उत्तर नहीं है, जैसा कि @gnovice द्वारा समझाया गया है ।

संपादित करें

एक फ़ाइल के अंदर कई कार्यों को परिभाषित करने का एक और तरीका जो बाहर से सुलभ है, एक फ़ंक्शन बनाने के लिए है जो कई फ़ंक्शन हैंडल लौटाता है । दूसरे शब्दों में, आप अपने डिफाइनिंग फंक्शन को कॉल करेंगे [fun1,fun2,fun3]=defineMyFunctions, जिसके बाद आप out1=fun1(inputs)आदि का उपयोग कर सकते हैं ।


मैं इस उद्देश्य के लिए ऊप का उपयोग नहीं करूंगा, यह विशेष रूप से स्थिर तरीकों के लिए पर्याप्त ओवरहेड जोड़ता है। ( stackoverflow.com/questions/1693429/… )
डैनियल

1
@ डैनियल: ओवरहेड केवल तभी ध्यान देने योग्य होता है जब आप बड़ी मात्रा में फंक्शन कॉल करते हैं और विधि में गणना अर्ध-तात्कालिक होती है। दोनों स्थितियां अक्सर खराब डिज़ाइन की ओर इशारा करती हैं - कोई सदिशीकरण, और अर्थहीन कार्य नहीं। इस प्रकार, मैं बहुत चिंतित नहीं होगा।
जोनास

23

मैं वास्तव में SCFrench का जवाब पसंद करता हूं - मैं यह बताना चाहता हूं कि असाइनमेंट फ़ंक्शन का उपयोग करके इसे आसानी से कार्यक्षेत्र में सीधे आयात करने के लिए संशोधित किया जा सकता है । (इसे इस तरह करना मुझे बहुत सारे पायथन के "आयात x से y" चीजों को करने के तरीके की याद दिलाता है)

function message = makefuns
  assignin('base','fun1',@fun1);
  assignin('base','fun2',@fun2);
  message='Done importing functions to workspace';
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end

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

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1

assignin('caller',...)अधिक सही होगा। आप इन फ़ंक्शन को किसी अन्य फ़ंक्शन के भीतर से उपयोग करना चाह सकते हैं।
क्रिस लुएंगो

10

SCFrench के उत्तर के समान ही लाइनों के साथ, लेकिन अधिक C # स्टाइल स्पिन के साथ।

मैं कई स्थिर तरीकों से युक्त एक क्लास (और अक्सर करता हूँ) करूँगा। उदाहरण के लिए:

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end

जैसे-जैसे विधियाँ स्थिर होती हैं, आपको कक्षा में प्रवेश करने की आवश्यकता नहीं होती है। आप कार्यों को इस प्रकार कहते हैं:

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     

4

मैं ऑक्टेव के साथ एक .m फ़ाइल में कई फ़ंक्शन परिभाषित करता हूं और फिर .m फ़ाइल के भीतर से कमांड का उपयोग करता हूं जहां मुझे उस फ़ाइल से फ़ंक्शन का उपयोग करने की आवश्यकता होती है:

source("mycode.m");

यकीन नहीं होता कि यह मतलूब के साथ उपलब्ध है।

octave:8> help source
'source' is a built-in function

 -- Built-in Function:  source (FILE)
     Parse and execute the contents of FILE.  This is equivalent to
     executing commands from a script file, but without requiring the
     file to be named `FILE.m'.

3

आप मुख्य फ़ंक्शन के साथ एक मुख्य फ़ाइल में समूह कार्यों को भी इस तरह देख सकते हैं:

function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} ); 

% paste your subfunctions below ....
function str=subfun1
str='hello'

तब सबफ़न 1 को कॉल करना इस तरह दिखेगा: str = main ('सबफ़न 1')


0

R2017b के रूप में, यह आधिकारिक तौर पर संभव नहीं है। प्रासंगिक दस्तावेज कहा गया है कि:

प्रोग्राम फ़ाइलों में कई फ़ंक्शन हो सकते हैं। यदि फ़ाइल में केवल फ़ंक्शन परिभाषाएँ हैं, तो पहला फ़ंक्शन मुख्य फ़ंक्शन है, और फ़ंक्शन है जो MATLAB फ़ाइल नाम के साथ संबद्ध है। मुख्य फ़ंक्शन या स्क्रिप्ट कोड का पालन करने वाले फ़ंक्शंस को स्थानीय फ़ंक्शन कहा जाता है। स्थानीय कार्य केवल फ़ाइल के भीतर उपलब्ध हैं।

हालांकि, अन्य उत्तरों में सुझाए गए वर्कअराउंड कुछ समान प्राप्त कर सकते हैं।


यह बिल्कुल नहीं है जो गनोविस ने अपने उत्तर की शुरुआत में कहा था?
आदिल

@ एडियल शायद, लेकिन उस जवाब के बाद से कई साल बीत चुके थे, और किसी को कुछ भी बदलने पर आश्चर्य हो सकता है।
देव-आईएल

मैं अभी भी नहीं मिला अगर कुछ भी बदल गया है ...? :)
आदिल

नहीं। शायद कुछ प्रलेखन के अलावा जो इस विशिष्ट विषय को संबोधित करने के लिए जोड़ा गया था।
देव-आईएल

मैंने यह उत्तर क्यों लिखा इसका कारण यह है कि कई रिलीज से पहले उन्होंने ऐसे फ़ंक्शंस पेश किए जिन्हें आप स्क्रिप्ट के अंत में जोड़ सकते हैं - इसलिए कोई भी आश्चर्यचकित हो सकता है अगर इस संबंध में कुछ भी बदल जाए (उत्तर: नहीं)।
देव-आईएल

-1

मेरे पास SCFRench के साथ और ओक्टेव पर Ru Hasha के साथ प्रयास है ।

और अंत में यह काम करता है: लेकिन मैंने कुछ संशोधन किया है

function message = makefuns
    assignin('base','fun1', @fun1);   % Ru Hasha
    assignin('base', 'fun2', @fun2);  % Ru Hasha
    message.fun1=@fun1;               % SCFrench
    message.fun2=@fun2;               % SCFrench
end

function y=fun1(x)
    y=x;
end

function z=fun2
    z=1;
end

अन्य 'एम' फ़ाइल में बुलाया जा सकता है:

printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());

अपडेट करें:

मैंने एक उत्तर जोड़ा क्योंकि तो +72 और ही +20 ने मेरे लिए सप्तक में काम किया । मैंने जो लिखा वह पूरी तरह से काम करता है (और मैंने पिछले शुक्रवार को इसका परीक्षण किया जब मैंने बाद में पोस्ट लिखा)।


2
यदि आप बता सकते हैं कि यह उन दो मौजूदा उत्तरों से अलग है जिनसे आप कॉपी कर रहे हैं, तो मैं अपना डाउनवोट हटा दूंगा। पहले टिप्पणी न करने के लिए क्षमा करें। मैं सिर्फ यह नहीं देखता कि यह अलग कैसे है, सिवाय इसके कि आपने दोनों विधियों को एक फ़ंक्शन में जोड़ा और इसलिए कुछ निरर्थक कर रहे हैं। इसके अलावा, कृपया आपके द्वारा संदर्भित उत्तरों के लिए उचित लिंक डालें, "+72" और "+20" काफी गूढ़ हैं, मुझे यह महसूस करने में थोड़ा समय लगा कि आप वोट काउंट का जिक्र कर रहे हैं, जो समय के साथ बदल जाएगा और आपके संदर्भ बना देगा अस्पष्ट।
संकट लुएंगो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.