使用 Python 實現複製粘貼的功能

楔子

pandas 裏面有一個 pd.read_clipboard 函數,可以根據你複製的內容生成 DataFrame。是的,就是我們平時選中,然後 Ctrl+C 時拷貝的內容。所以比較神奇,那麼 pandas 到底是怎麼做到的,它是怎麼讀出我們使用 Ctrl +C 複製的內容呢。

看了一下源碼,不同的操作系統使用的複製方式不同,Windows 比較複雜,方法是使用了 ctypes,然後調用了操作系統的一個動態庫實現的;而 macOS 和 Linux 比較簡單,調用的是內置的命令。

下面我們來看看如何在這三個系統上實現複製粘貼的功能。

Windows 上的複製粘貼

我們說 Windows 是使用 ctypes 調用動態庫實現的,比較麻煩。但是我們知道 Python 有一個 pywin32 模塊,對於 Windows 操作系統提供的接口進行了封裝。所以在 Windows 上我們會使用 pywin32 來實現複製粘貼功能。

該模塊直接通過 pip install pywin32 安裝即可。

import win32clipboard as wcb
import win32con as wc

# 打開復制粘貼板
wcb.OpenClipboard()
# 我們之前可能已經 Ctrl + C 了
# 這裏是清空目前 Ctrl + C 複製的內容
# 但顯然沒有這一步也無所謂,因爲第二次複製會覆蓋第一次複製的內容
wcb.EmptyClipboard()
# 將內容寫入複製粘貼板,第一個參數是 win32con.CF_TEXT
# 第二個參數是我們要複製的內容,編碼的時候指定爲 "gbk"
wcb.SetClipboardData(wc.CF_TEXT, "古明地覺".encode("gbk"))
# 關閉複製粘貼板
wcb.CloseClipboard()

然後我們 Ctrl+V 粘貼就會得到 "古明地覺" 這個字符串,另外編碼的時候要使用 gbk,因爲我當前操作系統默認編碼使用的是 gbk,所以會對我們輸入的字節使用 gbk 解碼。因此如果使用 utf-8 編碼的話,那麼粘貼之後得到的就會是亂碼。當然具體編碼根據你當前的機器決定。

複製我們實現了,下面來看看怎麼實現粘貼。

import win32clipboard as wcb
import win32con as wc

wcb.OpenClipboard()
# 獲取粘貼板內容,既然是獲取,那麼只需要一個參數即可
# 會返回已經使用 Ctrl + C 複製的內容
data = wcb.GetClipboardData(wc.CF_TEXT)
# 關閉複製粘貼板
wcb.CloseClipboard()

# 然後隨便 Ctrl+C 拷貝一段內容
# 下面就會將拷貝的內容打印出來
print(data.decode("gbk"))

還是很簡單的,我們上面使用的模塊是 win32 系列,所以它只適用於 Windows 系統。那如果我想在 Linux 和 macOS 中實現怎麼辦呢?也很簡單,事實上,這兩個系統實現起來反而會更簡單,因爲自帶了相關的命令。

macOS 上的複製粘貼

macOS 自帶了相關命令,我們只需要通過 subprocess 模塊去調用即可,舉個例子:

非常簡單,那麼代碼要如何實現呢?

import subprocess

# 實現拷貝
def copy(text):
    p = subprocess.Popen(["pbcopy", "w"],
                         stdin=subprocess.PIPE,
                         close_fds=True)
    # 將內容拷貝起來,注意 macOS 的編碼默認是 utf-8
    p.communicate(input=text.encode("utf-8"))

# 實現粘貼
def paste():
    p = subprocess.Popen(["pbpaste", "r"],
                         stdout=subprocess.PIPE,
                         close_fds=True)
    stdout, stderr = p.communicate()
    # 返回粘貼內容
    return stdout.decode("utf-8")

copy("古明地覺的編程教室")
print(paste())  # 古明地覺的編程教室

以上代碼在 macOS 上執行,由於自帶了複製粘貼相關的命令,操作起來就比 Windows 方便多了。

Linux 上的複製粘貼

Linux 也提供了複製粘貼的命令,叫 xclip,但這個命令不是自帶的,我們需要使用 yum 安裝。

import subprocess

# 實現拷貝
def copy(text):
    p = subprocess.Popen(
        ["xclip", "-selection", "c"], 
        stdin=subprocess.PIPE, close_fds=True
    )
    p.communicate(input=text.encode("utf-8"))

# 實現粘貼   
def paste():
    p = subprocess.Popen(
        ["xclip", "-selection", "c", "-o"], 
        stdout=subprocess.PIPE, close_fds=True
    )
    stdout, stderr = p.communicate()
    return stdout.decode("utf-8")

但其實在 Linux 上通過命令實現複製粘貼沒什麼意義,因爲我們都是通過 SSH 遠程連接到公司的服務器,這種情況下 xclip 是不生效的。

當然,感覺這個功能也沒多大用,當做興趣瞭解一下就行。

pyperclip 實現複製粘貼

最後我們再來介紹一個模塊,叫 pyperclip,它對不同的操作系統的複製粘貼功能進行了封裝,可以簡化我們的操作。舉個例子:

import pyperclip

# 複製
pyperclip.copy("哼哼")
# 粘貼
print(pyperclip.paste())  # 哼哼

還是很方便的,以後就可以使用這個模塊,自動幫我們屏蔽了操作系統間的差異。另外,這個模塊只支持複製文本。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/wLhxP9YFPIt590zMpadtUA