какой стиль программирования ОО в R станет читабельным для программиста на Python? - PullRequest
15 голосов
/ 10 февраля 2011

Я являюсь автором пакета журналирования в CRAN, я не считаю себя программистом R, поэтому я попытался сделать его совместимым по коду со стандартным пакетом журналирования Python как мог, но теперь у меня есть вопрос.и я надеюсь, что это даст мне возможность узнать больше R!

, это о иерархических регистраторах.в Python я создал бы регистратор и отправил бы ему записи регистрации:

l = logging.getLogger("some.lower.name")
l.debug("test")
l.info("some")
l.warn("say no")

В моем пакете R вместо этого вы не создаете регистратор, которому вы отправляете сообщения, вы вызываете функцию, где один из аргументов являетсяИмя регистратора.что-то вроде

logdebug("test", logger="some.lower.name")
loginfo("some", logger="some.lower.name")
logwarn("say no", logger="some.lower.name")

проблема в том, что вам нужно повторять имя регистратора каждый раз, когда вы хотите отправить ему сообщение регистрации.Я думал, я мог бы создать частично примененный функциональный объект и вызвать его вместо этого, что-то вроде

logdebug <- curry(logging::logdebug, logger="some.lower.logger")

, но тогда мне нужно сделать это для всех функций отладки ...

как бы выR пользователи подходят к этому?

Ответы [ 3 ]

27 голосов
/ 11 февраля 2011

Похоже на работу для справочного класса ?setRefClass, ?ReferenceClasses

Logger <- setRefClass("Logger",
                  fields=list(name = "character"),
                  methods=list(
                    log = function(level, ...) 
                          { levellog(level, ..., logger=name) },
                    debug = function(...) { log("DEBUG", ...) },
                    info = function(...) { log("INFO", ...) },
                    warn = function(...) { log("WARN", ...) },
                    error = function(...) { log("ERROR", ...) }
                    ))

, а затем

> basicConfig()
> l <- Logger$new(name="hierarchic.logger.name")
> l$debug("oops")
> l$info("oops")
2011-02-11 11:54:05 NumericLevel(INFO):hierarchic.logger.name:oops
> l$warn("oops")
2011-02-11 11:54:11 NumericLevel(WARN):hierarchic.logger.name:oops
> 
3 голосов
/ 02 марта 2011

Это можно сделать с помощью пакета proto. Это поддерживает более старые версии R (это было в течение многих лет), поэтому у вас не будет проблемы старых и новых версий R.

library(proto)
library(logging)

Logger. <- proto(
        new = function(this, name)
            this$proto(name = name),
        log = function(this, ...) 
            levellog(..., logger = this$name),
        setLevel = function(this, newLevel) 
            logging::setLevel(newLevel, container = this$name),
        addHandler = function(this, ...)
            logging::addHandler(this, ..., logger = this$name), 
        warn = function(this, ...)
            this$log(loglevels["WARN"], ...),
        error = function(this, ...)
            this$log(loglevels["ERROR"], ...) 
)
basicConfig()
l <- Logger.$new(name = "hierarchic.logger.name")
l$warn("this may be bad")
l$error("this definitely is bad")

Это дает вывод:

> basicConfig()
> l <- Logger.$new(name = "hierarchic.logger.name")
> l$warn("this may be bad")
2011-02-28 10:17:54 WARNING:hierarchic.logger.name:this may be bad
> l$error("this definitely is bad")
2011-02-28 10:17:54 ERROR:hierarchic.logger.name:this definitely is bad

В приведенном выше примере мы просто наложили прототип поверх логирования, но можно было бы превратить каждый регистрируемый объект в прототип, т. Е. Это было бы и то и другое, поскольку и объекты логирования, и объекты прото являются средами R. Это избавило бы от лишнего слоя.

Подробнее см. http://r -proto.googlecode.com .

1 голос
/ 10 февраля 2011

Зачем вы повторяете имя?Было бы удобнее передать объект журнала непосредственно в функцию, то есть

logdebug("test",logger=l)
# or
logdebug("test",l)

Немного, как можно использовать соединения в ряде функций.Я думаю, это более правильный способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...