Kuruluş modunda iki farklı kod bloğuna ortak bir kod bloğu ekleyebilir miyim?


13

org-modeVeri tablosu ve ondan farklı özetleri ayıklamak için iki Python kod bloğu içeren bir dosya var .

Bu iki kod bloğu arasında bazı ortak sabitleri ve işlevleri paylaşmak istiyorum. İdeal olarak, diğer iki bloktan biri değerlendirildiğinde otomatik olarak dahil edilecek ve değerlendirilecek olan ortak kodu ayrı bir kod bloğuna faktoring ederek bunu yapardım. Uydurma sözdiziminde aşağıdaki gibi görünecektir:

#+NAME: init_block
#+BEGIN_SRC python
  ... common constants and functions here ...
#+END_SRC

#+NAME: summary_1
#+BEGIN_SRC python :prepend init_block
  ... data-processing code depending on init code goes here ...
#+END_SRC

#+NAME: summary_2
#+BEGIN_SRC python :prepend init_block
  ... more processing which also depends on init code ...
#+END_SRC

:sessionSeçeneği kullanabileceğimi düşünüyorum , ama iki nedenden dolayı yapmamayı tercih ederim. İlk olarak, C-c C-cbir kod bloğunda her kullandığımda sıfırdan çalışan bir durum yerine durum bilgisi olan bir sistem kurar . İkincisi ve ilgili olarak, şimdi dosyayı her açtığımda ortak başlatma kodunu manuel olarak değerlendirmeyi hatırlamak zorundayım: Sadece veri tablosunu güncelleyemiyorum, özet bloklarından birine gidip C-c C-cgüncellemek için vurdum .

Bunu yapmanın iyi bir yolu var mı?

Yanıtlar:


16

Bunu en kolay şekilde , okuryazar programlama için org- babel'in noweb referans sözdizimini kullanarak yapabilirsiniz . İşte bir örnek:

* Initialization block containing function definition
#+NAME: init_block
#+BEGIN_SRC python
  constant=19
  def some_function(x):
    return constant * x
#+END_SRC

* Call the function on an integer
#+BEGIN_SRC python :noweb yes 
  <<init_block>>
  return some_function(13)
#+END_SRC

#+RESULTS:
: 247

* Call the function on a string
:PROPERTIES:
:noweb:    yes
:END:

#+BEGIN_SRC python
  <<init_block>>
  return some_function('abc')
#+END_SRC

#+RESULTS:
: abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc

Teşekkür ederim. Harika görünüyor, hackish çözümümden çok daha iyi. Önümüzdeki birkaç gün içinde deneyeceğim ve herhangi bir sorunum olup olmadığını göreceğim.
Jon O.

@JonO. teşekkürler - Bu yanıt sizin için çalışırsa o zaman doğru olarak kabul misiniz
kaldırılmış

4

Biraz daha düşündükten sonra bu soruna kısmi bir çözüm buldum. Kullanır :session, ancak en azından diğer bloklardan birini değerlendirmeden önce ortak başlatma kodunun her zaman otomatik olarak çalıştırılmasını sağlayabilirim. 'Hile' başlık bloğuna atıfta bulunan ve her seferinde değerlendirilmesine neden olan sahte bir başlık değişkeni kullanmaktır:

#+NAME: init_block
#+BEGIN_SRC python :session t
  constant=19
  def some_function(x):
    return constant * x
#+END_SRC

#+BEGIN_SRC python :session t :var dummy=init_block
some_function(13)
#+END_SRC

#+RESULTS:
: 247

Şimdi tanımları değiştirebilir init_blockve kullanan başka bir blok değerlendirildiğinde otomatik olarak yeniden değerlendirilmesini sağlayabilirsiniz :var dummy=init_block. Bu, tanımların init_blockidempotent ve vatansız olması koşuluyla iyi çalışır .

(Python bloklarını :sessionmoda değiştirirken return, işlevsel modda bloktan bir değer döndürmek için gereken ifadeleri kaldırmanız gerektiğini unutmayın).

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.