İthalat / Bağımlılıkların ne zaman kullanılacağına dair daha iyi açıklama


152

" R Uzantılarını Yazma " kılavuzu, İçe Aktarmalar veya Bağımlıların ne zaman kullanılacağına ilişkin aşağıdaki rehberliği sağlar:

Genel kurallar

  • Kitaplığı kullanarak paketi yüklemek için yalnızca ad alanı gereken paketler (pkgname), 'Bağımlılar' alanında değil 'İçe Aktarmalar' alanında listelenmelidir.
  • Paketi kullanarak kitaplığı (pkgname) başarıyla yüklemek için eklenmesi gereken paketler, yalnızca 'Bağımlılar' alanında listelenmelidir.

Birisi bu konuda biraz daha netlik sağlayabilir mi? Paketimin yalnızca ad alanlarının yüklenmesine ihtiyacı olduğunda ve eklenmesi gereken bir pakete ihtiyacım olduğunda nasıl anlarım? Her ikisinin örnekleri nelerdir? Bence tipik paket, bazen başka paketlerdeki işlevleri çağıran bir işlevler koleksiyonudur (burada bazı çalışmalar zaten kodlanmıştır). Yukarıdaki senaryo 1 veya 2 mi?

Düzenle

Bu belirli konuyla ilgili bir bölüm içeren bir blog yazısı yazdım ('İthalat ve Bağlıdır' için arama yapın). Görseller anlaşılmasını çok kolaylaştırıyor.


1
Blog yazınız, modülleri planlamaya başladığımda bana paket yapısı hakkında her şeyi anlattı . Teşekkürler!
Konrad Rudolph

Yanıtlar:


148

"Imports"olduğundan daha güvenlidir "Depends"(ve aynı zamanda onu kullanan bir paketi, kullanılan diğer paketlere göre 'daha iyi bir vatandaş' yapar "Depends").

Bir "Depends"yönerge, diğer paketi ana arama yoluna (yani tarafından döndürülen ortamların listesi search()) ekleyerek başka bir paketten bir işlevin kullanılabilir olmasını sağlamaya çalışır . Bununla birlikte, daha sonra yüklenen başka bir paket, arama yoluna daha önce aynı şekilde adlandırılmış bir işlevi yerleştirirse, bu strateji engellenebilir. (Chambers soda ) fonksiyonunun örneğini kullanarak, "gam"hem de bulunur, gamve mgcvpaketler. gamBiri bağlı, diğeri bağlı olmak üzere iki paket daha yüklenmişse, mgcvçağrılar tarafından bulunan işlev, gam()bu iki paketin eklendiği sıraya bağlı olacaktır. İyi değil.

Bir "Imports"yönerge , normal arama yolu yerine işlevleri yerleştirilecek <imports:packageName>(hemen sonra aranacak <namespace:packageName>) herhangi bir destekleyici paket için kullanılmalıdır . Yukarıdaki örnekte yer alan paketlerden biri "Imports"mekanizmayı kullanıyorsa (bu aynı zamanda dosyada gerekli importveya importFromdirektifleri gerektirir NAMESPACE), meseleler iki şekilde iyileştirilebilir. (1) Paket, hangi mgcvişlevin kullanılacağı üzerinde kontrol sahibi olacaktır . (2) Ana arama yolunu içe aktarılan nesnelerden uzak tutmak, diğer paketin diğer mgcvişleve olan bağımlılığını potansiyel olarak bozmayacaktır .

Ad alanlarının kullanılmasının bu kadar iyi bir uygulama olmasının nedeni budur, neden şimdi CRAN tarafından uygulanmaktadır ve (özellikle) kullanımın kullanmaktan "Imports"daha güvenli olmasının nedeni budur "Depends".


Önemli bir uyarı eklemek için düzenlendi:

Orada bir yukarıdaki tavsiye maalesef yaygın istisna: paketiniz bir paket dayanıyorsa Akendisi "Depends"başka paket üzerinde B, paketiniz olasılıkla takmak gerekir Abir ile "Dependsdirektifi.

Bunun nedeni , paketteki işlevlerin A, paket Bve işlevlerinin search()yola ekleneceği beklentisiyle yazılmış olmasıdır .

Bir "Depends"yönerge paketi yükleyecek ve ekleyecektir A, bu noktada paketin Akendi "Depends"yönergesi bir zincirleme reaksiyonda paketin Byüklenmesine ve eklenmesine neden olacaktır. Paketteki işlevler Adaha sonra Bbağlı oldukları paketteki işlevleri bulabilecekler .

Bir "Imports"yönerge şekilde yükleyip olacak değil paketini takmak Ave irade ne yük ne de paketini takmak B. ( "Imports", Sonuçta bu paket yazarlar ad mekanizmasını kullanıyor ve bu paket beklediğini Akullanıyor olacak "Imports"herhangi fonksiyonlara noktasına B. O erişmeleri gerektiğini) paketinde herhangi fonksiyonlara Fonksiyonlarınızdan tarafından Aramalar Apaket işlevleri itimat Birade sonuç olarak başarısız olur.

Yalnızca iki çözüm şunlardan biridir:

  1. Paketinizin Abir "Depends"yönerge kullanarak paket eklemesini sağlayın .
  2. Uzun vadede daha iyi, paketin bakımcısıyla iletişime Ageçin ve ad alanlarını oluşturmak için daha dikkatli bir iş yapmalarını isteyin ( bu ilgili cevapta Martin Morgan'ın ifadesiyle ).

1
Yakın zamanda benzer bir soru soran ve son zamanlarda bu sorunlarla güçlü bir şekilde boğuşan, bunlar ince ve çoğu zaman kötü iletilen kavramlardır. Başka bir açıklama için sizi burada yönlendireceğim: stackoverflow.com/questions/7880355/…
Bryan Hanson

@BryanHanson - Bu bağlantıdaki notları yazdığınız için teşekkürler. Wrt sürüm gereksinimleri arasındaki farklar Importsve dosyalardaki Dependsörneklerin kontrol edilmesi .Rdgerçekten ince ve bilinmeye değer.
Josh O'Brien

1
Bağımlılıklarla ilgili 'Bağımlı' seçeneğini kullanan uyarı korkunç bir şeydir. Bu demek oluyor ki, diğer herkes de gelene kadar paketimde 'İthalat'ı kullanamayacağım. = (
Ken Williams

Hala tam olarak Imports: ggplot2bilmediğim bir şey, eğer bir paket yazıyorsam ve yapmak istiyorsam , o zaman paketim neden autoplotişlevi bulamıyor ? Açıkçası Dependspaket kitaplığını ekler ggplot2ve bu nedenle herhangi bir sorun yoktur. Örneğin autoplot.myFunction() , @import ggplot2etiketi kullanan bir işlevim var ve paketimde var Imports: ggplot2ama bir hata alıyorum: Error in eval(expr, envir, enclos) : could not find function "autoplot"onu kullanmaya çalıştığımda.
nathaneastwood

1
@Willem Teşekkürler. Elbette haklısınız ve yanıltıcı içeriği temizlemek için yanıtı düzenledim. Bunu cevaplamayı karmaşık hale getiren şeyin bir kısmı, OP sorusunu Dependsve Importsbölümlerine atıfta bulunarak çerçevelendirirken DESCRIPTION, gerçekten bir işlevi "içeri aktarmanın" (ona "bağlı olmak" yerine) ne anlama geldiğini sormasıdır. Bu soru cevaplamaya çalıştığım soru olduğu için (ve - şüpheliyim - bu cevabı arayan çoğu insanın bilmek istediği şey), aksi takdirde cevabı değiştirmeden bırakacağım.
Josh O'Brien

32

Hadley Wickham kolay bir açıklama yapıyor ( http://r-pkgs.had.co.nz/namespace.html ):

Bir paketi ikisinden birinde listelemek Dependsveya Importsgerektiğinde yüklenmesini sağlar. Temel fark, Importspaketi sadece yüklediği yere Dependseklemesidir. Başka hiçbir fark yok. [...]

Aksi iyi bir neden olmadığı sürece, sen her zaman liste paketleri gerektiği Importsdeğil Depends. Bunun nedeni, iyi bir paketin kendi kendine yetmesi ve küresel ortamda (arama yolu dahil) değişiklikleri en aza indirmesidir. Bunun tek istisnası, paketinizin başka bir paketle birlikte kullanılmak üzere tasarlanmış olmasıdır. Örneğin, analog paket veganın üzerine inşa edilir. Vegan olmadan işe yaramaz, bu yüzden Dependsyerine vegan var Imports. Benzer şekilde, ggplot2 gerçekten İçe Aktarmaktan ziyade ölçeklere bağlı olmalıdır.


15

SfDA'daki Odalar, bu paket bir 'ad alanı' mekanizması kullandığında ve artık tüm paketlerin bunlara sahip olması gerektiği için 'İthalat'ı kullanmasını söylüyor, o zaman yanıt her zaman' İthalatlar 'olabilir. Geçmişte paketler aslında ad alanlarına sahip olmadan yüklenebilirdi ve bu durumda Depends'i kullanmanız gerekirdi.


2
bir paket "içe aktarmalar" bölümünde belirtildiğinde ve pakette bir işlev kullanmak istediğimde, kendi işlevlerimin kitaplığı (...) çağırması gerekir mi yoksa tüm işlevler arama yolunda zaten mevcut mu? Ayrıca, SfDA nedir? bağlantılar?
SFun28

2
Veri Analizi Yazılımı : springer.com/statistics/computanional+statistics/book/… ... sorularınıza gelince, cevabı önceden bilmiyorum, ancak minimal bir test paketini kolayca hackleyebilir ve cevabı bulabilirsiniz.
ampirically

1
SfDA == "Veri Analizi için Yazılım". [65] r-project.org/doc/bib/R-books.html adresinde . Bir paket başka bir paketi belirtiyorsa, konsolda library () veya require () kullandığınızda, bağımlıların (şifrelerin) yüklenmesi ve içe aktarılması (ations) hakkında bilgi veren bir mesaj görmelisiniz. Evet, o zaman ulaşılabilir olmalılar.
IRTFM

4
+1 - Bu benim de güçlü izlenimim. Ayrıca, ithalatta belirtilen bir paket, bir <namespace:packageName>parçası olarak hemen ardından aranacaktır <imports:packageName>. Başka bir çağrıya library()gerek yoktur ve R, Imported paketi bulunamazsa , paket yükleme zamanında konsolda sizi bilgilendirmez .
Josh O'Brien

6

Hangisini kullanacağınıza karar vermenize yardımcı olacak basit bir soru:

Paketiniz, son kullanıcının başka bir paketin işlevlerine doğrudan erişmesini gerektiriyor mu?

  • HAYIR -> İthalatlar (en yaygın cevap)
  • EVET -> Bağlıdır

"Bağımlı" seçeneğini kullanmanız gereken tek zaman, paketinizin bir eklenti veya başka bir paketin arkadaşı olduğu, son kullanıcınızın hem paketinizdeki hem de kodundaki "Bağımlı" paketindeki işlevleri kullanacağı zamandır. Son kullanıcınız yalnızca işlevlerinizle arabirim oluşturacaksa ve diğer paket yalnızca perde arkasında çalışacaksa, bunun yerine 'İçe Aktarmalar'ı kullanın.

Bu konudaki uyarı, genellikle yapmanız gerektiği gibi 'İçe Aktarmalar'a bir paket eklerseniz, kodunuzun tam ad alanı sözdizimini kullanarak, örneğin dplyr::mutate()sadece yerine bu paketin işlevlerine başvurması gerektiğidir mutate(). Kodu okumayı biraz daha hantal yapar, ancak daha iyi ambalaj hijyeni için ödenmesi gereken küçük bir bedeldir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.