script - lista de modulos de python
Cómo importar solo una función de otro paquete, sin cargar todo el espacio de nombres (2)
Con la advertencia de que no estoy muy familiarizado con el entorno R y los espacios de nombres, ni si esto funcionaría en un paquete; una solución que he usado en programación es usar ::
para copiar la función en mi propia función.
Puede tener consecuencias desconocidas al cargar todo el paquete, como se discutió en los comentarios a la pregunta de OP, pero parece no asociar los nombres de funciones del paquete al espacio de nombres R y enmascarar nombres de funciones existentes.
Ejemplo:
my_memisc_description <- memisc::description
Supongamos que estoy desarrollando un paquete, llamado foo
, que desea utilizar la función de description
del paquete memisc
. No quiero importar todo el espacio de nombres memisc
porque:
- Es malo
-
memisc
anula la función baseaggregate.formula
, que rompe varias cosas. Por ejemplo, elexample(aggregate)
fallaría miserablemente.
El paquete incluye los siguientes archivos:
DESCRIPCIÓN
Package: foo
Version: 0.0
Title: Foo
Imports:
memisc
Collate:
''foo.R''
NAMESPACE
export(bar)
importFrom(memisc,description)
R / foo.R
##'' bar function
##''
##'' @param x something
##'' @return nothing
##'' @importFrom memisc description
##'' @export
`bar` <- function(x) {
description(x)
}
Creo que el uso de importFrom
no cargaría todo el espacio de nombres memisc
, sino únicamente namespace::description
, pero este no es el caso. Comenzando con una R vainilla:
R> getS3method("aggregate","formula")
## ... function code ...
## <environment: namespace:stats>
R> library(foo)
R> getS3method("aggregate","formula")
## ... function code ...
## <environment: namespace:memisc>
R> example(aggregate)
## Fails
Entonces, ¿sabes cómo puedo importar la función de description
de memisc
sin obtener aggregate.formula
en mi entorno?
No puedes.
Si declara memisc
en el campo Imports:
, el espacio de nombres se cargará cuando se cargue el paquete y el paquete podrá encontrar los objetos exportados. (Si lo especifica en Depends:
el espacio de nombres se cargará y se adjuntará a la ruta de búsqueda que hace que los objetos exportados puedan ser encontrados por cualquier código).
Parte de cargar un espacio de nombres es registrar métodos con el genérico. (Miré pero no pude encontrar una documentación canónica que diga esto, NAMESPACE
al hecho de que las funciones se declaran como métodos S3 en el archivo NAMESPACE
como evidencia.) Los métodos definidos se guardan con el genérico y tienen la visibilidad del función genérica (o, tal vez, el espacio de nombre de la función genérica).
Típicamente, un paquete definirá un método ya sea para un genérico que crea o para una clase que define. El sistema de objetos S3 no tiene un mecanismo para definir formalmente una clase S3 (o qué paquete creó la clase), pero la idea general es que si el paquete define funciones que devuelven un objeto con ese atributo de clase (y es el único paquete que lo hace), esa clase es la clase de ese paquete. Si se cumple alguna de estas dos condiciones, no habrá ningún problema. Si el genérico está definido en el paquete, solo se puede encontrar si el paquete está adjunto; si la clase se define en el paquete, los objetos de esa clase solo existirían (y, por lo tanto, se enviarían) si el paquete se adjunta y utiliza.
En el ejemplo de memisc
, ninguno de los dos tiene memisc
. El aggregate
genérico se define en el paquete de stats
y el objeto de formula
también se define en el paquete de stats
(basado en ese paquete que define como as.formula
, [.formula
, etc.) ya que no es ni el memisc
genérico ni el objeto de un memisc
, los efectos se pueden ver incluso (y el método enviado) si memisc
simplemente se carga pero no se adjunta.
Para obtener otro ejemplo de este problema, pero con reorder.factor
, consulte Reordenar el factor que proporciona resultados diferentes, según qué paquetes se carguen .
En general, no es una buena práctica agregar métodos a genéricos para los cuales el paquete no controla ni el objeto ni el genérico; doblemente si anula un método en un paquete central; y atrozmente así que si no es una función compatible hacia atrás con la función existente en los paquetes centrales.
Para su ejemplo, es mejor que copie el código para memisc::describe
en su paquete, aunque ese enfoque tiene sus propios problemas y advertencias.