2

I use inspect.getsource to check the libs I imported:

In[52]: from django.views.generic import View
In[53]: view_code = inspect.getsource(View)
In[54]: len(view_code)
Out[54]: 3242

Retrieve the formatted codes

In[55]: print(view_code)

class View(object):
    """
    Intentionally simple parent class for all views. Only implements
    dispatch-by-method and simple sanity checking.
    """

    http_method_names = ['get', 'post', 'put',
                        'patch', 'delete', 'head', 'options', 'trace']

    def __init__(self, **kwargs):

I'd like to store the codes to my notes for further reference,
to do this, I have to scroll through the entire code with the purpose to copy it.
It's not convenient if the codes are long enough.

How could I copy the output of print to clipboard in a straight-forward way?

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138
  • 1
    Do you actually want a way to capture the result of `print` to the clipboard, or just a way to send the string to the clipboard without printing it? – abarnert Jun 15 '18 at 00:30

1 Answers1

6

Python doesn't have clipboard APIs built in, except as part of the tkinter GUI, but there are a number of libraries on PyPI that do.

For example, with pyperclip, you can copy any string you want to the clipboard like this:

In[56]: import pyperclip
In[57]: pyperclip.copy(view_code)

But you may be able to use tkinter. Depending on your platform, whether you're using a console-mode or qtconsole session, etc., this may not work, or may require popping up an unwanted window, but you can try it and see:

In [119]: import tkinter
In [120]: tk = tkinter.Tk()
In [121]: tk.clipboard_clear()
In [122]: tk.clipboard_append(view_code)

If your setup does require you to display a window (e.g., I think this will happen in a console-mode session on Windows), you might still be able to do it without too much distraction. See this answer, suggested by J.Doe if you're interested.


But it might be simpler and more useful to just write to a file:

In[58}: with open('spam.txt', 'w') as f: f.write(view_code)

Or, since you're using IPython, you can use %save or various other magic commands. (See this question so I don't have to go over them all here.)


Or, there are multiple third-party implementations of IPython addons to give you clipboard copy commands, like this one (which I just found in a random search, so I'm not endorsing it or anything… but it seems to work):

In[61]: %clip view_code

If you actually need to capture the output of print for some reason, the two obvious ways to do it are to monkeypatch or shadow print, or to patch sys.stdout. For example:

import builtins
import io
import sys
def print(*args, **kw):
    if kw.get('file', sys.stdout) is sys.stdout:
        buf = io.StringIO()
        builtins.print(*args, **kw, file=buf)
        pyperclip.copy(buf.getvalue())
    builtins.print(*args, **kw)
abarnert
  • 354,177
  • 51
  • 601
  • 671
  • 1
    Actually, there is the Tkinter.Tk clipboard methods. – J. Doe Jun 15 '18 at 00:54
  • @J.Doe Good point. Presumably the OP is in a console-mode or qtconsole session, and using tkinter may, depending on the platform, either not work, or require popping up an unwanted window… but it will work in at least some cases; I'll add it to the answer. – abarnert Jun 15 '18 at 00:57
  • @J.Doe I already added one to the answer, but I'll link to that one for more detail. – abarnert Jun 15 '18 at 01:00
  • 1
    May want to mention the `tkinter`/`Tkinter` backwards incompatibility – J. Doe Jun 15 '18 at 01:01
  • @J.Doe I don't think it's necessary to mention Python 2 in questions about Python 3 in 2018. – abarnert Jun 15 '18 at 01:02
  • He technically didn't mention Python 3 – J. Doe Jun 15 '18 at 01:04
  • @J.Doe Also, if you really need to use Python 2.x, you have to deal with the way Tkinter mishandles Unicode until somewhere around 2.7.9, and the way it still mishandles astral characters after that. Not to mention that the whole `print` thing doesn't work, or even make sense, without a `__future__` declaration… – abarnert Jun 15 '18 at 01:05
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173184/discussion-between-j-doe-and-abarnert). – J. Doe Jun 15 '18 at 01:06