ما هو المكافئ عباءة من بيثون IDIOM "إذا __name__ ==" __main__ "؟

StackOverflow https://stackoverflow.com/questions/973106

  •  13-09-2019
  •  | 
  •  

سؤال

أنا dabably في عباءة وأوجه مشكلة في محاولة تحديد عباءة (و / أو LISP) أي ما يعادل هذا المصطلح المشترك بينثون.

IDIOM هو أنه في الجزء السفلي من وحدة Python، يوجد في كثير من الأحيان قليلا من رمز الاختبار، ثم عبارة يقوم بتشغيل التعليمات البرمجية، على سبيل المثال:

# mymodule.py
class MyClass(object):
    """Main logic / code for the library lives here"""
    pass

def _runTests():
    # Code which tests various aspects of MyClass...
    mc = MyClass() # etc...
    assert 2 + 2 == 4

if __name__ == '__main__': _runTests()

هذا مفيد لاختبار بسيط ومخصص. واحد عادة ما يستخدم هذه الوحدة عن طريق الكتابة from mymodule import MyClass, ، في أي حالة _runTests() لا يسمى أبدا، ولكن مع القصاص في النهاية، يمكن للمرء أيضا تشغيله عن طريق الكتابة python mymodule.py مباشرة من سطر الأوامر.

هل هناك تعادل معادلا في عباءة (و / أو LISP المشتركة)؟ أنا لست بعد مكتبة اختبار وحدة كاملة (حسنا، أنا، ولكن ليس في هذا السؤال)، أود فقط تضمين بعض التعليمات البرمجية في وحدة نمطية لن يتم تشغيلها إلا في بعض الحالات، حتى أتمكن من ذلك طريقة سريعة لتشغيل التعليمات البرمجية لقد كنت تعمل ولكن لا تزال تسمح باستيراد ملفي مثل وحدة نمطية / مساحة اسمية طبيعية.

هل كانت مفيدة؟

المحلول

إنه ليس oriomatic لتشغيل البرامج النصية عبقير مرارا وتكرارا من سطر الأوامر. الأداة هي سطر أوامر أفضل. Clojure كونها LISP، من الشائع إطلاق سراح عباءة وتترك نفس الحالة التي تعمل إلى الأبد، وتتفاعل معها بدلا من إعادة تشغيله. يمكنك تغيير الوظائف في مثيل التشغيل واحدا في وقت واحد، واجهتها وكزةها حسب الحاجة. الهروب من دورة التحرير / التحرير / التحرير / الترجمة البطيء البطيئة هي ميزة رائعة من Lisps.

يمكنك بسهولة كتابة الوظائف للقيام بأشياء مثل اختبارات وحدة التشغيل، وتصفح فقط تلك الوظائف من النتيجة كلما أردت تشغيلها وتجاهلها بطريقة أخرى. انها شائعة في عباءة لاستخدام clojure.contrib.test-is, ، أضف وظائف الاختبار الخاصة بك إلى مساحة اسمك، ثم استخدم clojure.contrib.test-is/run-tests لتشغيلها جميعا.

سبب وجيه آخر لعدم تشغيل Clojure من Commandline هو أن وقت بدء تشغيل JVM يمكن أن يكون باهظا.

إذا كنت ترغب حقا في تشغيل البرنامج النصي عباءة من سطر الأوامر، فهناك مجموعة من الطرق التي يمكنك القيام بها. يرى القائمة البريدية عبادة البلاغة لبعض المناقشة.

طريقة واحدة هي اختبار وجود وسيطات سطر الأوامر. ونظرا لهذا foo.clj في الدليل الحالي:

(ns foo)

(defn hello [x] (println "Hello," x))

(if *command-line-args*
  (hello "command line")
  (hello "REPL"))

ستحصل على سلوك مختلف اعتمادا كيف تبدأ العباء.

$ java -cp ~/path/to/clojure.jar:. clojure.main foo.clj --
Hello, command line
$ java -cp ~/path/to/clojure.jar:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (use 'foo)
Hello, REPL
nil
user=>

يرى src/clj/clojure/main.clj في مصدر Clojure إذا كنت تريد أن ترى كيف يعمل هذا.

هناك طريقة أخرى لتجميع التعليمات البرمجية الخاصة بك .class الملفات واستدعائها من سطر الأوامر Java. إعطاء ملف المصدر foo.clj:

(ns foo
  (:gen-class))

(defn hello [x] (println "Hello," x))

(defn -main [] (hello "command line"))

اجعل دليلا لتخزين مجمعة .class الملفات هذه الإعدادات الافتراضية إلى ./classes. وبعد يجب أن تجعل هذا المجلد بنفسك، فلن تخلقه. تأكد أيضا من ضبط $CLASSPATH لكي يتضمن ./classes والدليل مع شفرة المصدر الخاصة بك؛ سوف نفترض foo.clj في الدليل الحالي. لذلك من سطر الأوامر:

$ mkdir classes
$ java -cp ~/path/to/clojure.jar:./classes:. clojure.main
Clojure 1.1.0-alpha-SNAPSHOT
user=> (compile 'foo)
foo

في ال classes الدليل سيكون لديك الآن مجموعة من .class الملفات. لاستدعاء التعليمات البرمجية الخاصة بك من سطر الأوامر (تشغيل -main وظيفة افتراضيا):

$ java -cp ~/path/to/clojure.jar:./classes foo
Hello, command line.

هناك الكثير من المعلومات حول تجميع Clojure Code On clojure.org..

نصائح أخرى

أنا جديد جدا في عباء لكنني أعتقد هذه المناقشة على مجموعات Clojure قد تكون حل و / أو حلوة، على وجه التحديد منصب Stuart Sierra في 17 أبريل في الساعة 10:40 مساء.

في lisp المشتركة يمكنك استخدام القراءة الشرطية مع الميزات.

#+testing (run-test 'is-answer-equal-42)

سيتم قراءتها أعلاه فقط وبالتالي تنفيذ أثناء الحمل إذا كانت قائمة الميزات المنتصلة CL: * الميزات * سوف تحتوي على الرمز: الاختبار.

علي سبيل المثال

(let ((*features* (cons :testing *features*)))
   (load "/foo/bar/my-answerlib.lisp"))

سوف تضيف مؤقتا: اختبار إلى قائمة الميزات.

يمكنك تحديد الميزات الخاصة بك والتحكم في التعبيرات التي يقرأها نظام LISP المشترك والذي يتخطى.

بالإضافة إلى ذلك يمكنك أيضا القيام به:

#-testing (print '|we are in production mode|)

هناك أيضا قائمة بالإمكانيات المختلفة في http://rosettacode.org/wiki/script_main#clojure.. وبعد (إذا وجدت واحدة جديدة - يرجى إضافتها. ؛-))

قد ترغب في إلقاء نظرة على خصية مكتبة من Clojure-contrib. إنه ليس نفس المصطلح، لكن يجب أن يدعم سير عمل مشابه جدا.

توفر LISP المشتركة والجلد (وكذلك LISPs الأخرى) بيئة تفاعلية مع نطاق التشغيل، ولا تحتاج إلى حيل مثل «if __name__ == '__main__'». هناك بيئات مشابهة للإرشاد ل Python: Python من سطر الأوامر، iPython، وضع Python ل Emacs، إلخ.

يجب عليك فقط إنشاء المكتبة، وإضافة TestSuite لذلك (هناك العديد من أطر اختبار LISP المشتركة؛ أفضل 5 صباحا الإطار، هناك مسح للأطر المتاحة هنا). ثم قم بتحميل المكتبة، وفي العمارد، يمكنك القيام بأي شيء مع المكتبة: تشغيل الاختبارات، وظائف المكالمات، التجربة، إلخ.

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

إليك مثال على LISP المشترك (من مكتبة CL-SQLITE الخاصة بي):

الرمز:

(def-suite sqlite-suite)

(defun run-all-tests ()
  (run! 'sqlite-suite));'

(in-suite sqlite-suite)

(test test-connect
  (with-open-database (db ":memory:")))

(test test-disconnect-with-statements
  (finishes
    (with-open-database (db ":memory:")
      (prepare-statement db "create table users (id integer primary key, user_name text not null, age integer null)"))))
...

والجلسة التفاعلية:

CL-USER> (sqlite-tests:run-all-tests)
.......
 Did 7 checks.
    Pass: 7 (100%)
    Skip: 0 ( 0%)
    Fail: 0 ( 0%)

NIL
CL-USER> (defvar *db* (sqlite:connect ":memory:"))
*DB*
CL-USER> (sqlite:execute-non-query *db* "create table t1 (field text not null)")
; No value
CL-USER> (sqlite:execute-non-query *db* "insert into t1 (field) values (?)" "hello")
; No value
CL-USER> (sqlite:execute-to-list *db* "select * from t1")
(("hello"))
CL-USER> 

افترض الآن أنني وجدت علة في SQLite: تنفيذ إلى القائمة. أذهب إلى رمز هذه الوظيفة، وإصلاح الخطأ وإعادة ترجمة هذه الوظيفة. ثم استدعاء الوظيفة الثابتة وتأكد من أنها تعمل. لا تختفي قاعدة بيانات الذاكرة، ولها نفس الحالة كما كان قبل إعادة ترجمة.

حذاء طويل هو أدوات بناء (بديل لينيندين)، ذلك يدعم النصوص. وبعد لذلك يمكنك الحصول على نص تمهيد بدء #!/usr/bin/env boot التي يمكن أن يكون -main طريقة.

يمكنك أيضا إجراء مهام مستدقة من سطر الأوامر من شأنها استدعاء وظائف مختلفة من التعليمات البرمجية الخاصة بك. ويمكن أن يكون لديك مهمة التعبئة والتغليف يمكنها إنشاء Uberjar لأحد هذه الوظائف كأداة دخول.

إذا كنت تتحدث عن وجود "نقطة الدخول"، يمكنك بالتأكيد القيام بذلك:

(ns foo)

(defn foo [n]
  (inc n))

(defn main []
  (println "working")
  (println "Foo has ran:" (foo 1)))

(main)

ماذا سيحدث الآن هو أنه في أي وقت يكون هذا الرمز هو (تحميل ملف "foo" foo.clj ") 'd أو (استخدام" foo) أو (تتطلب "foo)، ثم سيتم استدعاء (الرئيسي)، والتي لا يتم ذلك عادة.

أكثر شيوعا هو أنه يمكن تحميل ملف من التعليمات البرمجية عند التشغيل، ثم سيتم استدعاء الدالة الرئيسية من قبل المستخدم.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top