it-swarm.asia

كسر/الخروج النصي

لدي برنامج يقوم ببعض تحليل البيانات ويبلغ طوله بضع مئات من الأسطر.

في وقت مبكر جدًا من البرنامج ، أرغب في القيام ببعض مراقبة الجودة ، وإذا لم تكن هناك بيانات كافية ، فأريد إنهاء البرنامج والعودة إلى وحدة التحكم R. خلاف ذلك ، أريد تنفيذ بقية الكود.

لقد جربت break و browser و quit ولا أحد منهم يوقف تنفيذ بقية البرنامج (و quit يوقف التنفيذ وكذلك الإقلاع التام عن R وهو أمر لا أريد حدوثه). الملاذ الأخير هو إنشاء عبارة if-else على النحو التالي:

 if(n < 500){}
 else{*insert rest of program here*}

ولكن هذا يبدو وكأنه ممارسة الترميز سيئة. هل فاتني شيء؟

65
user2588829

يمكنك استخدام الدالة stopifnot() إذا كنت تريد أن ينتج عن البرنامج خطأ:

foo <- function(x) {
    stopifnot(x > 500)
    # rest of program
}
48
Michael Malick

عكس البناء الخاص بك ، إذا:

if(n >= 500) {
  # do stuff
}
# no need for else
11
Thomas

تحرير: يبدو أن OP يقوم بتشغيل برنامج نصي طويل ، في هذه الحالة يحتاج المرء فقط إلى التفاف جزء من البرنامج النصي بعد مراقبة الجودة مع

if (n >= 500) {

.... long running code here

}

في حالة الخروج من وظيفة ، فربما تحتاج فقط إلى return() ، إما بشكل صريح أو ضمني.

على سبيل المثال ، عودة مزدوجة صريحة

foo <- function(x) {
  if(x < 10) {
    return(NA)
  } else {
    xx <- seq_len(x)
    xx <- cumsum(xx)
  }
  xx ## return(xx) is implied here
}

> foo(5)
[1] 0
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55

يعني return() ، أن السطر الأخير هو كما لو كنت قد انتهيت return(xx) ، ولكنه أكثر فعالية قليلاً في ترك المكالمة إلى return().

بعض النظر في استخدام عوائد متعددة نمط سيئة. في الوظائف الطويلة ، يمكن أن يصبح تتبع خروج الوظيفة أمرًا صعبًا أو عرضة للخطأ. وبالتالي ، يكون البديل هو الحصول على نقطة إرجاع واحدة ، ولكن يمكنك تغيير كائن الإرجاع باستخدام جملة if () else (). سيكون مثل هذا التعديل على foo()

foo <- function(x) {
  ## out is NA or cumsum(xx) depending on x
  out <- if(x < 10) {
    NA
  } else {
    xx <- seq_len(x)
    cumsum(xx)
  }
  out ## return(out) is implied here
}

> foo(5)
[1] NA
> foo(10)
 [1]  1  3  6 10 15 21 28 36 45 55
7
Gavin Simpson

ليست جميلة ، ولكن هنا طريقة لتنفيذ أمر exit() في R والذي يعمل لي.

exit <- function() {
  .Internal(.invokeRestart(list(NULL, NULL), NULL))
}

print("this is the last message")
exit()
print("you should not see this")

تم اختباره بشكل خفيف فقط ، ولكن عندما أقوم بتشغيل هذا ، أرى this is the last message ثم أجهض البرنامج النصي دون أي رسالة خطأ.

5
jochen

ربما تريد فقط إيقاف تنفيذ برنامج نصي طويل في مرحلة ما. أي. وكأنك تريد تشفير رمز الخروج () في C أو Python.

print("this is the last message")
stop()
print("you should not see this")
3
netskink

هذا سؤال قديم ولكن لا يوجد حل نظيف بعد. من المحتمل أن هذا لا يجيب على هذا السؤال بالتحديد ، لكن من يبحث هنا عن إجابات عن "كيفية الخروج بأمان من نص R". يبدو أن مطوري R نسوا تطبيق دالة exit (). على أي حال ، الخدعة التي وجدتها هي:

continue <- TRUE

tryCatch({
     # You do something here that needs to exit gracefully without error.
     ...

     # We now say bye-bye         
     stop("exit")

}, error = function(e) {
    if (e$message != "exit") {
        # Your error message goes here. E.g.
        stop(e)
    }

    continue <<-FALSE
})

if (continue) {
     # Your code continues here
     ...
}

cat("done.\n")

بشكل أساسي ، يمكنك استخدام علامة للإشارة إلى استمرار أو عدم وجود كتلة محددة من التعليمات البرمجية. ثم تستخدم الدالة stop() لتمرير رسالة مخصصة إلى معالج الأخطاء لوظيفة tryCatch(). إذا استقبل معالج الخطأ رسالتك للخروج بأمان ، فسيتجاهل الخطأ ويعين إشارة الاستمرار على FALSE.

1
user2641103

يمكنك استخدام دالة pskill في حزمة "أدوات" R لمقاطعة العملية الحالية والعودة إلى وحدة التحكم. بشكل ملموس ، لدي الوظيفة التالية المحددة في ملف بدء التشغيل الذي أصدره في بداية كل برنامج نصي. يمكنك أيضًا نسخه مباشرةً في بداية الكود. ثم أدخل halt() في أي وقت في الكود الخاص بك لإيقاف تنفيذ البرنامج النصي أثناء الطيران. تعمل هذه الوظيفة بشكل جيد على GNU/Linux واستناداً إلى وثائق R ، يجب أن تعمل أيضًا على Windows (لكنني لم أقم بالتحقق).

# halt: interrupts the current R process; a short iddle time prevents R from
# outputting further results before the SIGINT (= Ctrl-C) signal is received 
halt <- function(hint = "Process stopped.\n") {
    writeLines(hint)
    require(tools, quietly = TRUE)
    processId <- Sys.getpid() 
    pskill(processId, SIGINT)
    iddleTime <- 1.00
    Sys.sleep(iddleTime)
}
1
François Tonneau

هنا:

if(n < 500)
{
    # quit()
    # or 
    # stop("this is some message")
}
else
{
    *insert rest of program here*
}

سيتم إنهاء كل من quit() و stop(message). إذا كنت تقوم بتحديد مصدر البرنامج النصي من موجه الأوامر R ، فستخرج quit() من R كذلك.

0
stackoverflowuser2010