Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing Python objects in reticulate without `$`

Tags:

r

reticulate

The R package reticulate has a custom $ operator which acts as the . operator in the equivalent Python modules/objects. Since the second argument of $ cannot be evaluated, how do you pass an argument to it in this scenario?

The example usage on the reticulate README is

library(reticulate)
os <- import("os")
os$chdir("tests")
os$getcwd()

I'm after the following function where ... would be the python call with zero or more arguments.

my_function <- function(python_object, ...)

The python_object needs to be of class python.builtin.object or python.builtin.module and the arguments would need to be passed as characters since the functions don't exist in the global environment.

eg.

my_function(os, "chdir", "tests")
my_function(os, "getcwd")
my_function(r_to_py("my_string"), "lstrip", "my_")

My thoughts were something along the lines of

do.call("chdir", list("tests"), envir = os)

or

reticulate:::`$.python.builtin.object`(os, eval(parse(text="chdir('tests')")))

however neither of these have worked.

like image 868
ruaridhw Avatar asked Jul 18 '26 21:07

ruaridhw


1 Answers

Was achieved much simpler than I imagined...

my_function <- function(python_module, attribute, ...) {
  py_call(python_module[[attribute]], ...)
}

In general, $ is shorthand for [[.


Update

@jjallaire pointed out...

py_call is a lower level function which doesn't currently get the benefit of type wrapping (but it certainly should).

To return identical output (ie inherits the correct classes) as $ use either:

  • do.call(python_module[[attribute]], args = list(function_args))
  • python_module[[attribute]](function_args)

instead of py_call

See rstudio/reticulate#149.

like image 100
ruaridhw Avatar answered Jul 21 '26 11:07

ruaridhw



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!