programing

함수의 소스 코드를 보려면 어떻게 해야 합니까?

i4 2023. 6. 15. 21:34
반응형

함수의 소스 코드를 보려면 어떻게 해야 합니까?

함수의 소스 코드를 보고 작동 방식을 확인하고 싶습니다.다음 프롬프트에 이름을 입력하여 기능을 인쇄할 수 있습니다.

> t
function (x) 
UseMethod("t")
<bytecode: 0x2332948>
<environment: namespace:base>

이경우, 무이엇은 입니까?UseMethod("t") 코드를 를 들어, 균평? 실제로 사용 중인 소스 코드를 찾는 방법은 다음과 같습니다.t(1:10)?

제가 봤을 때와 다른 점이 있나요?UseMethod그리고 내가 봤을 때standardGeneric그리고.showMethods와 마찬가지로with?

> with
standardGeneric for "with" defined from package "base"

function (data, expr, ...) 
standardGeneric("with")
<bytecode: 0x102fb3fc0>
<environment: 0x102fab988>
Methods may be defined for arguments: data
Use  showMethods("with")  for currently available ones.

다른 경우에는 R 함수가 호출되는 것을 볼 수 있지만, 해당 함수의 소스 코드를 찾을 수 없습니다.

> ts.union
function (..., dframe = FALSE) 
.cbind.ts(list(...), .makeNamesTs(...), dframe = dframe, union = TRUE)
<bytecode: 0x36fbf88>
<environment: namespace:stats>
> .cbindts
Error: object '.cbindts' not found
> .makeNamesTs
Error: object '.makeNamesTs' not found

다음과 같은 기능을 찾으려면 어떻게 해야 합니까?.cbindts그리고..makeNamesTs?

여전히 다른 경우에는 약간의 R 코드가 있지만 대부분의 작업은 다른 곳에서 수행되는 것 같습니다.

> matrix
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 
{
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
    .Internal(matrix(data, nrow, ncol, byrow, dimnames, missing(nrow), 
        missing(ncol)))
}
<bytecode: 0x134bd10>
<environment: namespace:base>
> .Internal
function (call)  .Primitive(".Internal")
> .Primitive
function (name)  .Primitive(".Primitive")

무엇을 알아내려면 어떻게 해야 합니까?.Primitive기능이 있습니까?마찬가지로, 몇몇 함수들은 다음을 호출합니다..C,.Call,.Fortran,.External또는.Internal그것들의 소스 코드를 어떻게 찾을 수 있습니까?

UseMethod("t")는 것을 말해주고 있습니다.t()는 다른 객체 클래스에 대한 메서드를 갖는 (S3) 일반 함수입니다.

S3 방식 배차 시스템

S3 클래스의 경우 다음을 사용할 수 있습니다.methods특정 일반 함수 또는 클래스에 대한 메서드를 나열하는 함수입니다.

> methods(t)
[1] t.data.frame t.default    t.ts*       

   Non-visible functions are asterisked
> methods(class="ts")
 [1] aggregate.ts     as.data.frame.ts cbind.ts*        cycle.ts*       
 [5] diffinv.ts*      diff.ts          kernapply.ts*    lines.ts        
 [9] monthplot.ts*    na.omit.ts*      Ops.ts*          plot.ts         
[13] print.ts         time.ts*         [<-.ts*          [.ts*           
[17] t.ts*            window<-.ts*     window.ts*      

   Non-visible functions are asterisked

않는 표시됨"은합니다."보이지 않는 함수는 별표로 표시됨"은 패키지의 네임스페이스에서 함수를 내보내지 않음을 의미합니다.는 여히다통소볼코수있다니습드를을 볼 수 .::: 함즉, 함수)stats:::t.ts) 또는 를 사용하여getAnywhere().getAnywhere()함수가 어떤 패키지에서 왔는지 알 필요가 없기 때문에 유용합니다.

> getAnywhere(t.ts)
A single object matching ‘t.ts’ was found
It was found in the following places
  registered S3 method for t from namespace stats
  namespace:stats
with value

function (x) 
{
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)
}
<bytecode: 0x294e410>
<environment: namespace:stats>

S4 방식 배차 시스템

S4 시스템은 새로운 방법 파견 시스템이며 S3 시스템의 대안입니다.다음은 S4 기능의 예입니다.

> library(Matrix)
Loading required package: lattice
> chol2inv
standardGeneric for "chol2inv" defined from package "base"

function (x, ...) 
standardGeneric("chol2inv")
<bytecode: 0x000000000eafd790>
<environment: 0x000000000eb06f10>
Methods may be defined for arguments: x
Use  showMethods("chol2inv")  for currently available ones.

출력물은 이미 많은 정보를 제공합니다. standardGeneric는 S4 함수의 표시기입니다.정의된 S4 메소드를 확인하는 방법은 유용하게 제공됩니다.

> showMethods(chol2inv)
Function: chol2inv (package base)
x="ANY"
x="CHMfactor"
x="denseMatrix"
x="diagonalMatrix"
x="dtrMatrix"
x="sparseMatrix"

getMethod다음 방법 중 하나의 소스 코드를 확인하는 데 사용할 수 있습니다.

> getMethod("chol2inv", "diagonalMatrix")
Method Definition:

function (x, ...) 
{
    chk.s(...)
    tcrossprod(solve(x))
}
<bytecode: 0x000000000ea2cc70>
<environment: namespace:Matrix>

Signatures:
        x               
target  "diagonalMatrix"
defined "diagonalMatrix"

또한 각 방법에 대해 더 복잡한 서명이 있는 방법이 있습니다. 예를 들어

require(raster)
showMethods(extract)
Function: extract (package raster)
x="Raster", y="data.frame"
x="Raster", y="Extent"
x="Raster", y="matrix"
x="Raster", y="SpatialLines"
x="Raster", y="SpatialPoints"
x="Raster", y="SpatialPolygons"
x="Raster", y="vector"

이러한 방법 중 하나에 대한 소스 코드를 보려면 전체 서명을 제공해야 합니다.

getMethod("extract" , signature = c( x = "Raster" , y = "SpatialPolygons") )

부분 서명을 제공하는 것만으로는 충분하지 않습니다.

getMethod("extract",signature="SpatialPolygons")
#Error in getMethod("extract", signature = "SpatialPolygons") : 
#  No method found for function "extract" and signature SpatialPolygons

내보내지 않은 함수를 호출하는 함수

ts.union,.cbindts그리고..makeNamesTs는 서내보않함다에서 않은 입니다.stats네임스페이스입니다. 않은 는 다을사내않함소볼있수를 하여 볼 수 .::: 또는 연자또는getAnywhere.

> stats:::.makeNamesTs
function (...) 
{
    l <- as.list(substitute(list(...)))[-1L]
    nm <- names(l)
    fixup <- if (is.null(nm)) 
        seq_along(l)
    else nm == ""
    dep <- sapply(l[fixup], function(x) deparse(x)[1L])
    if (is.null(nm)) 
        return(dep)
    if (any(fixup)) 
        nm[fixup] <- dep
    nm
}
<bytecode: 0x38140d0>
<environment: namespace:stats>

컴파일된 코드를 호출하는 함수

"compiled"는 컴파일러 패키지에 의해 생성된 바이트 컴파일 R 코드를 의미하지 않습니다.<bytecode: 0x294e410>위 출력의 line은 함수가 바이트 컴파일되었음을 나타내며, R 명령줄에서 소스를 계속 볼 수 있습니다.

라고 부르는 .C,.Call,.Fortran,.External,.Internal또는.Primitive컴파일된 코드에서 엔트리 포인트를 호출하므로 함수를 완전히 이해하려면 컴파일된 코드의 소스를 살펴봐야 합니다.R 소스 코드의 이 GitHub 미러는 시작하기에 괜찮은 장소입니다.함수pryr::show_c_sourceGitHub의 할 수 가 될 수 ..Internal그리고..Primitive는 출호를 사용할 수 . 패키지가 사용할 수 있습니다..C,.Call,.Fortran,그리고..External하지만 아닙니다..Internal또는.PrimitiveR 인터프리터에 내장된 함수를 호출하는 데 사용되기 때문입니다.

위 함수 중 일부에 대한 호출은 문자열 대신 개체를 사용하여 컴파일된 함수를 참조할 수 있습니다.이 경우 개체는 클래스입니다."NativeSymbolInfo","RegisteredNativeSymbol"또는"NativeSymbol"그리고 물체를 인쇄하면 유용한 정보를 얻을 수 있습니다.를 들면, 들면를예,optim 출들.External2(C_optimhess, res$par, fn1, gr1, con)로 그건 (으)야.C_optimhess,것은 아니다."C_optimhess").optim 패키지에 를 할 수 .stats:::C_optimhess호출 중인 컴파일된 함수에 대한 정보를 확인합니다.

패키지에서 컴파일된 코드

패키지의 컴파일된 코드를 보려면 패키지 원본을 다운로드/언팩해야 합니다.설치된 이진 파일이 충분하지 않습니다.패키지의 원본 코드는 패키지가 원래 설치된 것과 동일한 CRAN(또는 CRAN 호환) 저장소에서 사용할 수 있습니다.download.packages()함수는 패키지 소스를 가져올 수 있습니다.

download.packages(pkgs = "Matrix", 
                  destdir = ".",
                  type = "source")

하는 "Matrix Matrix"가 저장됩니다..tar.gz파일을 현재 디렉토리에 저장합니다.는 컴일된코는에서 할 수 .src압축되지 않은 파일 및 태그가 지정되지 않은 파일의 디렉터리입니다.압축 해제 및 해제 단계는 외부에서 수행할 수 있습니다.R 또는내서에 에서.R 사용untar()기능. 를 한 할 수 으로 한 을 풀 수 다운로드 및 확장 단계를 하나의 통화로 결합할 수 있습니다(이 방법으로 한 번에 하나의 패키지만 다운로드하고 압축을 풀 수 있습니다).

untar(download.packages(pkgs = "Matrix",
                        destdir = ".",
                        type = "source")[,2])

또는 GitHub, R-Forge 또는 RForge.net 등을 통해 패키지 개발이 공개적으로 호스팅되는 경우 소스 코드를 온라인으로 찾아볼 수 있습니다.

기본 패키지에서 컴파일된 코드

특정 패키지는 "기본" 패키지로 간주됩니다.이러한 패키지는 R과 함께 제공되며 해당 패키지의 버전은 R 버전에 고정됩니다. 예는 다음과 같습니다.base,compiler,stats,그리고.utils따라서 위에서 설명한 것처럼 CRAN에서 별도의 다운로드 가능 패키지로 사용할 수 없습니다.대신, 이들은 개별 패키지 디렉토리의 R 소스 트리의 일부입니다./src/library/R 소스에 액세스하는 방법은 다음 절에서 설명합니다.

R 인터프리터에 내장된 컴파일된 코드

R 인터프리터에 내장된 코드를 보려면 R 소스를 다운로드/패킹 해제해야 합니다. 또는 R Subversion 저장소 또는 Winston Chang의 Github 미러를 통해 온라인으로 소스를 볼 수 있습니다.

Uwe Ligges의 R 뉴스 기사(PDF)(p.43)는 소스 코드를 보는 방법에 대한 좋은 일반적인 참조입니다..Internal그리고..Primitive 기단계먼다저음함이찾것수입다는니름을에서 함수 입니다.src/main/names.c "C-entry" 합니다.src/main/*.

에 대한 의 소스 수를 들어 이 질 과 그 에 대 답 외 에 도 있 알 에 패 필 함 키 지 소 대 있 코 좋 방 있 얻 수 을 를 는 은 드 이 습 법 니 다스한에수어문떤없 이패키중복요지지는한른대다▁for ▁if▁in▁we▁without▁source▁function▁it▁here▁on▁want▁code▁for좋▁e이'▁the▁package방있▁source 예를 들어 소스를 원하는 경우randomForest::rfcv():

팝업 창에서 보기/편집하기

edit(getAnywhere('rfcv'), file='source_rfcv.r')

View(getAnywhere('rfcv'), file='source_rfcv.r')

:edit()편집기를 .View()스프레드시트 스타일의 데이터 뷰어를 호출합니다.

  • View()다중 브라우저 데이터를 검색하는 데는 좋지만 일반적으로 장난감 길이 이외의 코드에는 적합하지 않습니다.
  • 그래서 코드만 보고 싶을 때,edit() IMO보다 ?View()▁with와 함께.edit()R 함수의 최대 70%를 차지할 수 있는 모든 arg-parsing/checking/default/error-message 로직을 접고 함수가 실제로 어떤 작업을 수행하는지(!), 반환 유형이 어떤 개체인지, 재귀 여부 및 방법인지 등을 확인할 수 있습니다.

별도의 파일로 리디렉션하려면(즐겨찾기 IDE/편집기의 코드를 불러오거나 grep/ 등으로 처리할 수 있도록):

capture.output(getAnywhere('rfcv'), file='source_rfcv.r')

경우, R는 비시함의경, R base는 원는포함함라고 하는 합니다.body()함수의 본문을 반환합니다.를 들어, 들어는, 소스를의 .print.Date()기능을 볼 수 있습니다.

body(print.Date)

다음을 생성합니다.

{
    if (is.null(max)) 
        max <- getOption("max.print", 9999L)
    if (max < length(x)) {
        print(format(x[seq_len(max)]), max = max, ...)
        cat(" [ reached getOption(\"max.print\") -- omitted", 
            length(x) - max, "entries ]\n")
    }
    else print(format(x), max = max, ...)
    invisible(x)
}

만약 당신이 스크립트에서 작업하고 있고 함수 코드를 문자 벡터로 원한다면, 그것을 얻을 수 있습니다.

capture.output(print(body(print.Date)))

제공:

[1] "{"                                                                   
[2] "    if (is.null(max)) "                                              
[3] "        max <- getOption(\"max.print\", 9999L)"                      
[4] "    if (max < length(x)) {"                                          
[5] "        print(format(x[seq_len(max)]), max = max, ...)"              
[6] "        cat(\" [ reached getOption(\\\"max.print\\\") -- omitted\", "
[7] "            length(x) - max, \"entries ]\\n\")"                      
[8] "    }"                                                               
[9] "    else print(format(x), max = max, ...)"                           
[10] "    invisible(x)"                                                    
[11] "}"     

내가 왜 그런 일을 하고 싶겠어요?오브젝트를 .x서, 디에어class(x) = "foo" 으로 합니다. 목록을 기준으로 합니다.리스트 멤버 중 한 명("재미"라는 이름)은 기능이었고 저는 원했습니다.print.foo()들여쓰기된 함수 소스 코드를 표시합니다.그래서 저는 다음과 같은 토막글을 만들었습니다.print.foo():

sourceVector = capture.output(print(body(x[["fun"]])))
cat(paste0("      ", sourceVector, "\n"))

다음과 관련된 코드를 들여쓰기하고 표시합니다.x[["fun"]].

2020-12-31 편집

것을 덜 일한를얻위한덜우회법방인적기보동정▁a.character소스 코드의 벡터는 다음과 같습니다.

sourceVector = deparse(body(x$fun))

debug() 함수를 사용하여 디버깅하면 나타납니다.t() 전치 함수의 기본 코드를 확인하려고 합니다.'t'만 입력해도 많은 것이 드러나지 않습니다.

>t 
function (x) 
UseMethod("t")
<bytecode: 0x000000003085c010>
<environment: namespace:base>

그러나 'debug(functionName)'를 사용하여 기본 코드를 표시하고 내부를 검색합니다.

> debug(t)
> t(co2)
debugging in: t(co2)
debug: UseMethod("t")
Browse[2]> 
debugging in: t.ts(co2)
debug: {
    cl <- oldClass(x)
    other <- !(cl %in% c("ts", "mts"))
    class(x) <- if (any(other)) 
        cl[other]
    attr(x, "tsp") <- NULL
    t(x)
}
Browse[3]> 
debug: cl <- oldClass(x)
Browse[3]> 
debug: other <- !(cl %in% c("ts", "mts"))
Browse[3]> 
debug: class(x) <- if (any(other)) cl[other]
Browse[3]>  
debug: attr(x, "tsp") <- NULL
Browse[3]> 
debug: t(x)

EDIT: debug once()는 undebug()를 사용하지 않고도 동일한 작업을 수행합니다.

이것이 주요 답변의 흐름에 어떻게 들어맞는지 보지 못했지만 잠시 당황스러웠기 때문에 여기에 추가합니다.

Infix 연산자

연산자: infix 소의스코드보기자기)의 소스 코드를 보려면:%%,%*%,%in%), 사용getAnywhere항목:

getAnywhere("%%")
# A single object matching ‘%%’ was found
# It was found in the following places
#   package:base
#   namespace:base
#  with value
#
# function (e1, e2)  .Primitive("%%")

주요 답변은 거울을 사용하여 더 깊이 파고드는 방법을 다룹니다.

RStudio에는 (적어도) 3가지 방법이 있습니다.

  1. 커서가 기능에 있는 동안 F2 키를 누릅니다.
  2. Ctrl 또는 Command를 누른 상태에서 함수 이름 클릭
  3. View (와 같이 (function_name) (function_name) (functio 설바와같이위서명에한)

소스 코드와 함께 새 창이 열립니다.손이 닿으면.원시 또는 .C 다른 방법이 필요합니다. 죄송합니다.

RR에매우기있습다니능이한리편에 매우 .edit

new_optim <- edit(optim)

은 소스코엽다니의 를 열 입니다.optim R's 지정사용에 options그런 다음 편집하고 수정된 함수를 할당할 수 있습니다.new_optim나는 이 기능을 코드를 보거나 코드를 디버깅하는 것을 매우 좋아합니다. 예를 들어, 메시지나 변수를 인쇄하거나 추가 조사를 위해 글로벌 변수에 할당할 수도 있습니다(물론 사용할 수 있습니다).debug).

소스 코드를 보고 콘솔에 짜증나는 긴 소스 코드를 인쇄하지 않으려면 다음을 사용할 수 있습니다.

invisible(edit(optim))

C/C++ 또는 Fortran 소스 코드를 보는 데 사용할 수 없습니다.

그건 그렇고.edit는 목록, 행렬 등의 다른 개체를 열 수 있으며 이 개체는 속성이 있는 데이터 구조도 표시합니다. 기.deExcel과 같은 편집기(GUI에서 지원하는 경우)를 열어 매트릭스 또는 데이터 프레임을 수정하고 새 편집기를 반환하는 데 사용할 수 있습니다.이것은 때때로 유용하지만 일반적인 경우, 특히 행렬이 클 때는 피해야 합니다.

함수가 C/C++/Fortran이 아닌 순수 R로 작성되는 한, 다음을 사용할 수 있습니다.그렇지 않으면 디버깅하고 "jump into"를 사용하는 이 가장 좋습니다.

> functionBody(functionName)

View(function_name)예를 들면View(mean)대문자 [V]를 사용해야 합니다.읽기 전용 코드가 편집기에서 열립니다.

사해볼수있다니습을 해 볼 .print.function()S3 제네릭으로, 콘솔에 함수를 기록합니다.

함수의 소스 코드를 보려면 print()를 사용합니다.

f <- function(x){
     x * 2
 }

print(f)

function(x){
    x * 2
}

이 을 사용하지 않고 실행해 보세요.()

": 다의소코가져다옵니드를스예음▁▁the▁for다▁the▁example:니예"의 코드를 가져오겠습니다cat()함수:

cat
    if (is.character(file)) 
        if (file == "") 
            file <- stdout()
        else if (startsWith(file, "|")) {
            file <- pipe(substring(file, 2L), "w")
            on.exit(close(file))
        }
        else {
            file <- file(file, ifelse(append, "a", "w"))
            on.exit(close(file))
        }
    .Internal(cat(list(...), file, sep, fill, labels, append))

그러나 소스 코드 대신 "UseMethod"가 반환되는 경우가 있습니다.

▁source의 소스 ,read_xml():

library(xml2)
read_xml 
# UseMethod("read_xml")

그것은 우리에게 별로 쓸모가 없어요!이 경우 방법을 살펴봅니다.

methods("read_xml")
# read_xml.character* read_xml.connection* read_xml.raw* read_xml.response* 

그리고 위의 값에서 getAnywhere를 사용하여 소스 코드를 확인합니다.

getAnywhere("read_xml.character")

다른 예

다음에 대한 소스 코드를 확인해 보겠습니다.qqnorm():

qqnorm
# UseMethod("qqnorm") # Not very useful

methods("qqnorm")
# [1] qqnorm.default* # Making progress...

getAnywhere("qqnorm.default") # Shows source code!

PyCharm의 R-플러그인에 대한 빠른 해결책 (RStudio의 경우 @Arthur Yip의 답변 참조).필요한 경우 Editor 또는 R Console에서 기능 이름을 입력하고 선택합니다.그런 다음 "선언으로 이동"하거나 Ctrl-B 또는 Command-B 단축키를 사용합니다.참고: 이 기능은 다음에 유용하지 않습니다..Primitive 함수입니다

언급URL : https://stackoverflow.com/questions/19226816/how-can-i-view-the-source-code-for-a-function

반응형