Soru MATLAB'de öz referans mümkün mü?


Belirtildiği üzere İşte, paketlerdeki işlevlerin yanı sıra sınıflardaki statik yöntemler, yine de bir packagename.functionname sözdizimi veya import packagename.* için her işlevi (içe aktarmalar, işlev değil, çalışma alanının bir parçasıdır). Bu, daha sonra paket / sınıf adını değiştirmenin sıkıcı bir baş belası olabileceği anlamına gelir.

Gibi bir şey yapmanın bir yolu var mı import this.*aynı paket / sınıftaki tüm işlevlere / statik yöntemlere erişmek için bir paket / sınıf adı agnostik yöntem mi?


21
2018-04-12 14:37


Menşei


Bunun için bir cevap duymayı çok isterim ... - Andrey Rubshtein
@Andrey de öyle. Belki bir kelle bunun için bazı ustaca yöntem bulma konusunda yardımcı olacaktır ... Gnovice bir güzel hack Bu arada, ama çok fazla hesaplama zamanı harcadığını söyledi - Tobias Kienzler
Yeterince upvotes verirsek, belki de R2012a'ya eklerler? - Andrew Janke
@Andrew emin, bir atış verin ;-) O zamana kadar "doğru" cevabın sadece "Hayır" olduğunu sanıyorum, ama gerçekten ihtiyacınız varsa bu Hack tarafından Gnovice" - Tobias Kienzler


Cevaplar:


Yani ... bu da ithal edilmek için ithalat gerektirmiyor mu? Veya import, her zaman yolunda sahip olduğunuz bir işlev midir?

Her bir işlevin en üstünde bir "bunu içe aktar" bloğunu yapıştırmak çok daha karmaşık görünüyor, ve o zaman ithalatınız için endişelenmenize gerek yok. Yolda güvenin tehlikeli olduğunu hissetmeye eğilimliyim.

"Bunu İçe Aktar" bloğu

%% Import own package
[~, pkgdir] = fileparts(fileparts(mfilename('fullpath')));
import([pkgdir(2:end) '.*']);

Bir paket dizininde olduğundan emin olmak için bir try / catch bloğuna bile koyabilirsiniz ve değilse ne yapacağınıza karar verebilirsiniz.

%% Import own package
try
    [~, pkgdir] = fileparts(fileparts(mfilename('fullpath'))); 
    import([pkgdir(2:end)'.*']);
catch err
    if ~strcmp(err.identifier,'MATLAB:UndefinedFunction'), rethrow(err); end
end

6
2017-11-14 00:38



Temiz! teşekkür ederim - Tobias Kienzler
Ya da iç içe paketler için böyle bir şey: mfiledir = fileparts(mfilename); pkg_pos = strfind(mfiledir, [filesep '+']); if ~isempty(pkg_pos), import([strrep(mfiledir((pkg_pos(1)+2):end), [filesep '+'], '.') '.*']); end - Ken Chatfield


Muhtemelen bu bir ödül karşılığı bir cevap değildir, ancak herhangi bir cevabınız olmadığından, yine de yayınlayacağımı düşündüm! Statik yöntemleri, yalnızca bir kez tanımlamanız gereken sınıfın bir örneği aracılığıyla çağırabilirsiniz. İşlevleri bir işlev tanıtıcısı aracılığıyla çağırabilirsiniz, ancak bu işlev başına bir tanıtıcı gerektirir.

Bu teknikleri kullanarak tüm statik metodunuzu ve fonksiyon referanslarınızı tek bir yerde tanımlayabilirsiniz. Sonra bu referansları paketiniz boyunca kullanacaksınız. Daha sonra, paket adını daha sonra değiştirmeye karar verdiyseniz, yalnızca tek bir yerde saklanan bu referansları güncellemeniz gerekir.

Görmek:

Statik Yöntemleri Çağırmak

Ayrıca, sınıfın bir örneğini kullanarak statik yöntemleri de çağırabilirsiniz.   herhangi bir yöntem gibi:

obj = MyClass;

değer = obj.pi (.001);

function_handle (@) 

Aşağıdaki örnek, humps işlevi için bir işlev tanıtıcısı oluşturur.   ve değişken fhandle atar.

fhandle = @humps;


3
2017-10-26 07:33



neyse, nimet de olsa boşa gitmesine izin vermek utanç verici olur: -7 ama aynı zamanda cevabınız muhtemelen mümkün olan en yakın şeydir, bu yüzden gönderdiğiniz için teşekkürler - Tobias Kienzler


Son zamanlarda benzer bir problemle karşılaştım ve paketler için aşağıdaki çözümü buldum. Ancak çok hacky.

İsteğe bağlı argüman ile bunu içe aktarma denilen bir fonksiyon yaratırsınız.

function to_eval = importthis(exclude_list)
if nargin == 0
    exclude_list = [];
end
var_name = genvarname('A', exclude_list); %avoid shadowing
to_eval = ['[~,'...
    , var_name...
    , ']=fileparts(fileparts(mfilename(''fullpath'')));'... %get containing dir
    , 'eval([''import '','...
    , var_name...
    , '(2:end),''.*'']);'... %remove '+'
    , 'clear '... %clean up
    , var_name
    ];
end

Bu işlev daha sonra olabilecek bir dize döndürür eval"bu" paketi ithal eden ed. Paket işlevlerinizde aşağıdakileri en üste koyarsınız:

function B = myfunc(A)
eval(importthis);
%function body
end

Ayrıca geçebilirsin who için importhisİşlevinizin isim alanını temizler.

function B = myfunc(A)
eval(importthis(who));
%function body
end

Yaptığım şeyle gurur duyup hissetmemeye karar veremem.


3
2018-02-01 17:54



iyi iş! Kullanırsan galiba evalin('arayan', ...), dışarıdan tasarruf edebilirsiniz eval ve doğrudan arama yapmak importthis. Bu aynı zamanda bir cevaptır Bir dizini bir pakete nasıl dönüştürebilirim? - Tobias Kienzler
denedim evalin ama işe yaramıyor. Paketi olmayan bir dizin ismi almak da mümkündür. eval. Kukla bir istisna atabilir, yakalayabilir ve bir yığın izi içerdiğini kontrol edebilirsiniz. Ya da sadece kötüye kullanabilirsiniz dbstack. Bundan başka benim çözümüm, bağlı olduğunla aynı. - AE426082