Python脚本中NSPasteboard输出中的额外字符

DMf*_*fll 1 python nspasteboard

我的第一篇文章......

我正在使用python脚本从Mac OS X Lion上的剪贴板中获取文本.

我用以下函数设置了剪贴板:

def setClip (text):
    pb = NSPasteboard.generalPasteboard()
    pb.clearContents()
    a = NSArray.arrayWithObject_(text)
    return pb.writeObjects_(a)
Run Code Online (Sandbox Code Playgroud)

where text="some text"

我用以下内容检索剪贴板:

def getClip():
    pb = NSPasteboard.generalPasteboard()
    pbstring = pb.stringForType_(NSString *)dataType
    return pbstring
Run Code Online (Sandbox Code Playgroud)

输出前面带有"u",文本用引号括起,如下所示:

In [224]: setClip('some text')
Out[224]: True

In [225]: getClip()
Out[225]: "u'some text'"
Run Code Online (Sandbox Code Playgroud)

如何检索文本,因为它应该输入剪贴板?

我对NSPasteboard一无所知.我在stackoverflow上找到了这些代码片段.

提前致谢.

附录:我的实际代码

    from AppKit import *
    def setClip (text):
        pb = NSPasteboard.generalPasteboard()
        pb.clearContents()
        a = NSArray.arrayWithObject_(text)
        return pb.writeObjects_(a)

    def getClip():
        pb = NSPasteboard.generalPasteboard()
        pbstring = pb.stringForType_(NSString *)dataType
        return pbstring
Run Code Online (Sandbox Code Playgroud)

这就是我在ipython中运行它时会发生的事情:

输出前面带有"u",文本用引号括起,如下所示:

In [224]: setClip('some text')
Out[224]: True

In [225]: getClip()
Out[225]: "u'some text'"
Run Code Online (Sandbox Code Playgroud)

尝试了答案的建议***

def getClip():
    pb = NSPasteboard.generalPasteboard()
    return pb.stringForType_("public.utf8-plain-text")

In [332]: getClip()
Out[332]: u"some text"
Run Code Online (Sandbox Code Playgroud)

不行.:-(

是.我只需要这样做:

print getClip()
Run Code Online (Sandbox Code Playgroud)

我现在有

"some text"
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 5

如果你对NSPasteboard一无所知,你应该浏览一下" 粘贴板编程指南",并查看NSPasteboard类参考以获取详细信息.

您提供给我们的代码不一定是您正在运行的代码,因为:

pbstring = pb.stringForType_(NSString *)dataType
Run Code Online (Sandbox Code Playgroud)

这不是有效的Python.它位于ObjC和Python之间的某个地方.所以它只会提高一个SyntaxError.即使我把它变成了明智的东西:

pbstring = pb.stringForType_(dataType)
Run Code Online (Sandbox Code Playgroud)

或者,如果你想明确:

pbstring = pb.stringForType_(NSString.stringWithString_(dataType))
Run Code Online (Sandbox Code Playgroud)

这只是一个NameError,因为你没有dataType在任何地方定义.

那么,你从哪里来的dataType?好吧,参考文献stringForType:非常清楚:

在调用stringForType:之前,您必须发送类型或availableTypeFromArray :.

那么,如果我们打电话pb.types()怎么办?我们得到一个字符串列表,如下所示:

Out[153]: 
(
    "NeXT smart paste pasteboard type",
    "com.apple.webarchive",
    "NeXT Rich Text Format v1.0 pasteboard type",
    "public.utf8-plain-text",
    NSStringPboardType,
    …
)
Run Code Online (Sandbox Code Playgroud)

一些内置类型不会像来自Cocoa import*NSStringPboardType`的AppKit import*中的u"public.utf8-plain-text", but as string constants from one of the Cocoa libraries, likeNSStringPboardType 那样返回字符串文字.. If you've done,, or similar, you can just refer to it as

无论如何选择看起来合理的东西并使用它:

In [156]: pb.stringForType_(NSStringPboardType)
Out[156]: u'some text'
Run Code Online (Sandbox Code Playgroud)

一切都好!

那么,你为什么要"u'some text'"而不仅仅是u'some text'?我的猜测是,在你真正的代码,无论是setClipgetClip做额外的repr(s)地方.例如:

In [165]: s=u'some text'

In [166]: repr(s)
Out[166]: "u'some text'"

In [167]: s
Out[167]: u'some text'
Run Code Online (Sandbox Code Playgroud)

Out[166]可能看起来很熟悉.最有可能的是,你已经完成了代码中的等效操作.但是既然你没有在你向我们展示的代码中完成它,我们无法猜测到哪里.

正确的写作方式getClip()list按照您的偏好顺序制作类型,然后执行以下操作:

def getClip():
    pb = NSPasteboard.generalPasteboard()
    best_type = pb.availableTypeFromArray_(myFavoriteTypes)
    if best_type:
        return pb.stringForType_(best_type)
Run Code Online (Sandbox Code Playgroud)

这似乎是一种痛苦,而且是不必要的.难道你不能这样做return pb.stringForType_(best_type[0])并跳过那个完全availableTypeFromArray_废话吗?实际上,如果您想要的类型是NSStringPboardType,那么到目前为止,您可以使用每个版本的OS X来避开它,可能是宇宙中的每个程序,因为将文本放在剪贴板上是没有意义的以该格式提供.但它仍然是错误的,并且是一个坏习惯.(此外,也许您实际上更喜欢获得UTF-8字节而不是Unicode字符串,这在Python 2.x中可能更容易处理,或者在3.3中更有效.)

当你做正确的事情时,如果你只是getClip()在控制台上键入,你会看到u'some text'而不是'u"some text"'."但请坚持",你说,"那里仍然有一个'你'和一对引号,即使再没有两对引号,所以它仍然被打破了!" 不,这不对.看看这个:

In [182]: s=u'some text'

In [183]: s
Out[183]: u'some text'

In [184]: print s
some text
Run Code Online (Sandbox Code Playgroud)

或这个:

In [185]: s='some text'

In [186]: s
Out[186]: 'some text'

In [187]: print s
some text
Run Code Online (Sandbox Code Playgroud)

只要您在交互式控制台上键入字符串(或返回字符串的函数),它就会打印出带引号的字符串.但是引号实际上并不在字符串中 - 正如您在print显式使用该语句时所看到的那样.

所以,如果你看到这个:

In [332]: getClip()
Out[332]: u"some text"
Run Code Online (Sandbox Code Playgroud)

这实际上是正确的.它与s=u'some text'上面的例子相同.u字符串中没有引号或字符; 这就是交互式解释器显示您在命令行键入的字符串的方式.要验证它,只需print结果:

In [332]: print getClip()
some text
Run Code Online (Sandbox Code Playgroud)

或者将其存储在一个文件中:

In [188]: with open('test.txt', 'w') as f:
   .....:     f.write(getClip())
   .....:
Run Code Online (Sandbox Code Playgroud)

现在test.txt在你的文本编辑器中打开- 没有引号,没有u.