Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Python获取OS X中所有可用的打印机_Python_Python 3.x_Printing_Printers - Fatal编程技术网

使用Python获取OS X中所有可用的打印机

使用Python获取OS X中所有可用的打印机,python,python-3.x,printing,printers,Python,Python 3.x,Printing,Printers,目前我正在用Python对打印机进行一些测试,我正在尝试列出所有可用的打印机 现在我使用的库在连接类中公开了几个有用的API。其中还有getPrinters(): 以下是我使用的一个片段: >>> import cups >>> conn = cups.Connection () >>> printers = conn.getPrinters () >>> for printer in printers: ... p

目前我正在用Python对打印机进行一些测试,我正在尝试列出所有可用的打印机

现在我使用的库在
连接
类中公开了几个有用的API。其中还有
getPrinters()

以下是我使用的一个片段:

>>> import cups
>>> conn = cups.Connection ()
>>> printers = conn.getPrinters ()
>>> for printer in printers:
...     print printer, printers[printer]["device-uri"]
Brother_MFC_1910W_series
Photosmart_6520_series
我想知道是否有任何方法可以在不使用任何外部库的情况下编写上述代码。我很确定,如果不使用C语言,这是不可能做到的

如对文件有任何建议或参考,将不胜感激。谢谢


我使用的是Python3,您可以使用terminal命令
lpstat
()执行类似的查询。Python的内置
子流程
模块将允许您运行该命令并存储输出。某些文本解析应提供打印机名称

from subprocess import Popen, PIPE

# "lpstat -a" prints info on printers that can accept print requests
p = Popen(['lpstat', '-a'], stdin=PIPE, stdout=PIPE, stderr=PIPE)
output, errors = p.communicate()

lines = output.split('\n')
# check before you implement this parsing
printers = map(lambda x: x.split(' ')[0], lines)

可以将Python中的C库仅用于标准模块。参考文献:。将CUPS结构和调用转换为
ctypes
语法,我们得到的代码可以在标准OS X Python和Python 3下工作:

from __future__ import print_function

from ctypes import *


class cups_option_t(Structure):
    _fields_ = [
        ('name', c_char_p),
        ('value', c_char_p)
    ]


class cups_dest_t(Structure):
    _fields_ = [
        ('name', c_char_p),
        ('instance', c_char_p),
        ('is_default', c_int),
        ('num_options', c_int),
        ('cups_option_t', POINTER(cups_option_t))
    ]


cups_lib = cdll.LoadLibrary('/usr/lib/libcups.dylib')


if __name__ == '__main__':
    dests = cups_dest_t()
    dests_p = pointer(dests)    
    num_dests = cups_lib.cupsGetDests(byref(dests_p))    
    for i in range(num_dests):
        dest = dests_p[i]
        print(dest.is_default, dest.name)
        for j in range(dest.num_options):
            option = dest.cups_option_t[j]
            print('', option.name, option.value, sep='\t')    
    cups_lib.cupsFreeDests(num_dests, dests_p)

在使用
ctypes
时要特别小心,大多数错误都会产生分段错误。

激发向下投票。OSX附带CUPS,我想使用
pycups
戳它是有意义的。还有“核心打印层”,你可以使用
cffi
你的总体目标是什么。。。?你是否在尽量减少需要随应用程序分发的额外软件包的数量(同时尽可能保持“pythonic”?还是你只是在寻找在OSX上迭代打印机的最“pythonic”的方式?@Richard我的意思是完全避免使用库,这可能是在OSX和OSX上都有效的方法Win@Sid如果你想要一个跨平台的解决方案,你需要在问题中明确说明。如果我使用CUPS,那么我可以使用我提供的代码片段。那么任务是什么,你是说根本不去图书馆吗?CUPS是由Apple和所有其他接口开发的。我的意思是完全避免使用库,这可能在OSX和WinX上都适用。这两个目标有些矛盾。库的开发正是为了提供更抽象、更高级的API。上面的代码在Ubuntu 16.04上运行时没有任何更改。避免使用库的唯一方法是降低级别,例如使用
io.RawIOBase.write()
fcntl.ioctl()
直接写入打印机设备驱动程序。这会自动使您的代码绑定到特定的体系结构,并且不可移植。关于OSX和Windows上的跨平台打印:我只能想,它应该有一个绑定。另一个跨平台库。但是我不能给出更好的建议,我很久没有使用Qt了。是的,我也有同样的想法,但我想知道哪个是“Pythonic”方法
lpstat-a
只显示打印机名称和接受状态,这与上面的代码不等价。输出不保证具有标准格式,因此解析代码可能在不同的OSX版本中中断。