Cách chuyển một biến cho hàm magic ´run´ trong IPython


81

Tôi muốn làm một cái gì đó như sau:

In[1]: name = 'long_name_to_type_every_now_and_then.py'

In[2]: %run name

nhưng điều này thực sự cố gắng chạy 'name.py', đó không phải là điều tôi muốn làm.

Có cách chung nào để chuyển biến thành chuỗi không?

Một cái gì đó như sau:

In[3]: %run %name%

Vì lệnh tương đương với $ python file args, vì vậy tôi đoán là không thể.
Ashwini Chaudhary

Câu trả lời:


130

IPython mở rộng các biến với $namekiểu bash. Điều này đúng với tất cả các phép thuật , không chỉ %run.

Vì vậy, bạn sẽ làm:

In [1]: filename = "myscript.py"

In [2]: %run $filename
['myscript.py']

myscript.py chứa:

import sys
print(sys.argv)

Thông qua định dạng chuỗi lạ mắt của Python, bạn thậm chí có thể đặt các biểu thức bên trong {}:

In [3]: args = ["arg1", "arg2"]

In [4]: %run $filename {args[0]} {args[1][-2:]}
['myscript.py', 'arg1', 'g2']

5
Chỉ muốn đề cập rằng điều này cũng hoạt động rất độc đáo khi chỉ chạy các lệnh shell tùy ý sử dụng dấu chấm than (!) - xem tài liệu chính thức - ipython.org/ipython-doc/rel-0.10.2/html/interactive/…
yoniLavi

@minrk Chỉ là một câu hỏi đơn giản sự khác biệt giữa biến và biểu thức là gì. Biến từ điển có phải là một biểu thức không? Tôi hỏi vì theo ví dụ của bạn, tôi đã phải sử dụng định dạng chuỗi ưa thích để mở rộng từ điển nhưng không thành công khi tôi sử dụng $ thay thế. Tôi nghĩ danh sách, từ điển, v.v. đều là những loại biến đổi.
Stephen Jacob

Tôi đã thử điều đó trên %%htmlma thuật tế bào và nó không hoạt động. Có một cú pháp khác cho phép thuật ô so với phép thuật dòng không?
MROB

Tính đến phiên bản 7.3, một số magicschọn không tham gia mở rộng này, time, timeit, debugprun. github.com/ipython/ipython/pull/11516
hpaulj

11

Sử dụng get_ipython()để nhận tham chiếu đến InteractiveShell hiện tại , sau đó gọi magic()phương thức:

In [1]: ipy = get_ipython()

In [2]: ipy.magic("run foo.py")
ERROR: File `u'foo.py'` not found.

Chỉnh sửa Xem câu trả lời của minrk - đó là một cách tốt hơn nhiều để làm điều đó.


1
Trong khi điều này không phải là cách tốt nhất để làm điều đó, nó trả lời một câu hỏi của tôi, mà là làm thế nào để thực hiện ipython lệnh ma thuật trong một con trăn console (như trong, trong khi sử dụng spyder)
stuppie

1

Có vẻ như điều này là không thể với %runchức năng ma thuật được tích hợp sẵn . Tuy nhiên, câu hỏi của bạn đã dẫn tôi xuống một cái lỗ thỏ và tôi muốn xem làm điều gì đó tương tự sẽ dễ dàng như thế nào. Cuối cùng, có vẻ hơi vô nghĩa nếu cố gắng tạo ra một chức năng ma thuật khác mà chỉ sử dụng execfile(). Có thể điều này sẽ có ích cho ai đó, ở đâu đó.

# custom_magics.py
from IPython.core.magic import register_line_magic, magics_class, line_magic, Magics

@magics_class
class StatefulMagics(Magics):
    def __init__(self, shell, data):
        super(StatefulMagics, self).__init__(shell)
        self.namespace = data

    @line_magic
    def my_run(self, line):
        if line[0] != "%":
            return "Not a variable in namespace"
        else:
            filename = self.namespace[line[1:]].split('.')[0]
            filename += ".py"
            execfile(filename)
        return line

class Macro(object):
    def __init__(self, name, value):
        self.name = name
        self._value = value
        ip = get_ipython()
        magics = StatefulMagics(ip, {name: value})
        ip.register_magics(magics)

    def value(self):
        return self._value

    def __repr__(self):
        return self.name

Sử dụng cặp lớp này, (và được cung cấp một tập lệnh python tester.py), bạn có thể tạo và sử dụng biến "macro" với hàm ma thuật "my_run" mới được tạo như sau:

In [1]: from custom_magics import Macro

In [2]: Macro("somename", "tester.py")
Out[2]: somename

In [3]: %my_run %somename
I'm the test file and I'm running!
Out[3]: u'%somename'

Vâng, đây là một vụ hack lớn và có thể lãng phí. Theo cách đó, tôi tự hỏi liệu có cách nào để sử dụng tên liên kết với đối tượng Macro làm tên thực của macro hay không. Sẽ xem xét điều đó.


1

Trong trường hợp có thể có khoảng trống trong đối số, ví dụ: tên tệp, tốt hơn là sử dụng điều này:

%run "$filename"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.