pycharm 调试_把xlwings盘顺溜:xlwings连接到Pycharm进行调试,以及xlwings转换器等的使用...

4005e2c537b14895d5f38539cb62f7e5.png

说明:仅限windows平台

目录:

  • 零, xlwings能做什么
  • 一, 如何安装xlwings
  • 二,xlwings连接Pycharm调试器
  • 三, xlwings UDFs 编程的高级技巧
  • 四. 使用Pycharm对xlwings UDFs 进行交互式Debug

零, xlwings能做什么

它除了能够像pandas读写excel文件之外,还能够在windows平台上,给excel添加python宏功能。有了它,我们就能够在Excel的单元格的公式输入中,将我们的python函数当作普通的excel内置函数嵌入我们的公式,从而实现python与excel合而为一后便捷而强大的即时编辑功能。

一, 如何安装xlwings

请参考我写的另外一篇文章,详细介绍了它的安装:另一篇文章。

我们接着这篇文章的内容,继续深入介绍xlwings的使用。

二,xlwings连接Pycharm调试器

最终效果:通过将xlwings连接Pycharm调试器,我们就能够调试我们的自定义函数(UDF)。让UDF在被调用的过程中停留在Pycharm中设置好的断点上,并查看过程中产生的python变量,是不是极其炫酷呢?

参考:这里主要参考了xlwings官方文档的关于调试的部分中的“UDF debug server”章节。

详细步骤:

9059765e6be733232699160e587a0054.png
Excel中xlwings配置栏

上篇文章我们介绍了配置栏左侧两栏(Python,Conda)的使用。这次我们需要对剩余部分进行配置。(注意,由于作者本人的精力有限,因此只会介绍作者自己实际采用的配置方法,而不会详细介绍所有的配置方法和内部原理。)我们需要在右边两栏中两个勾选框都勾上。

然后启动Pycharm,在Pycharm中打开我们的表格对应的python程序,并把其中的主函数改成这样:

if __name__ == '__main__':
    xw.serve()

然后点击Pycharm的调试按钮(如下图)。注意这里千万不能通过点击“运行”按钮运行xlwings。

935618003bb5cfa8f53c1f3fde7f3b13.png

另外需要注意的是,pycharm在调试状态下运行的过程中,我们更改某个UDF后会立刻生效。但是,如果我们修改了UDF的函数名以及选项装饰器的参数,或者是添加或者删除了UDF,则需要在EXCEL的xlwings选项卡中点击“Import Functions”才会生效。

94f17de5fbac15f70eac53ed888ec6a4.png
Import Functions

三, xlwings UDFs 编程的高级技巧

我们在上篇文章中简单介绍了xlwings UDFs (自定义函数)的使用,但是当时的UDF的输入只是一个单元格,输出也只是一个单元格。如果想要执行更加复杂的输入输出,又该怎么办呢?比如说,我想直接把EXCEL中选定区域整体作为pandas 的 DataFrame 读入python程序,又该怎么做呢?

这就需要用到xlwings 的“转换器和选项”啦,当然我还是在学习的时候参考了xlwings文档中的相关章节。

该功能是通过给我们自己写的UDF加上一个装饰器来实现的,装饰器的语法如下:

@arg('x', convert=None, **kwargs)  # UDF输入选项

@ret(convert=None, **kwargs)  # UDF输出选项,ret是return的简写

下面介绍两个我常用的用法:

1,强制把输入当作一个矩阵(list的list)

它的使用情景是这样的:在默认的情况下,如果你在表格中选中了一个单元格然后传入UDF,那么python得到的将会是一个数值型变量。如果选中一行或者一列单元格传入,得到的是数值型变量构成的list。而如果传入的是一个单元格区域,那么得到的就会是list的list。这样,我们的python程序就需要对着三种情况分别做处理。更好的方法当然是强制把输入作为一个list的list,这就需要我们使用xlwings 的输入选项了:

# 相关程序核心代码
@xw.func
@xw.arg('x', ndim=2)      #我们这里介绍的输入选项 
@xw.ret(expand='table')
def count_spaces(x):
    return [[list(str(a)).count(" ") for a in b] for b in x]

这里我们实现了一个计算空格数的UDF,它的效果如下:

1c938d1a221a3b49c669664ca67f0e9a.png

2, 强制把输出扩展到其他单元格

细心的通过可能已经注意到了,前面我们的函数里面还使用了一个输出选项:

@xw.ret(expand='table')

这个选项的作用是强制把输出扩展到其他单元格。这么说可能不太好理解,具体来说就是你在一个单元格内写出自定义函数,然后按下“Ctrl+Shift+Enter”,UDF返回的数组就会从这个单元格向右或者向下扩展,直到把输出的list或者list like object一个单元格一个元素地完全写出来。

3, 从表格指定区域读取DataFrame

该功能也是通过xlwings 的“转换器和选项”实现的,代码如下:

@xw.func
@xw.arg('x', pd.DataFrame, index=1, header=1)
@xw.ret(index=True, expand='table')
def copy_df(x):
    return x

这里实现了读取一个dataframe并将它返回的UDF(import部分和main函数省略了),它的效果是这样的:

553786c74b8e8820168a0f540785c423.png
copy_df() 的效果

另外可以注意到,输入选项还使用了 index=1, header=1, 这和pandas中读取表格函数中的参数index, header的意义是相同的,分别指的表格的索引有几列,以及行名有几行。

四. 使用Pycharm对xlwings UDFs 进行交互式Debug

这部分是选学内容,算是作者对于自己喜欢的小技巧的推荐。

具体来说,这一部分讲的是,把UDF读取到的dataframe存储在pkl中,在另外一个编译器中重新读入pkl,并继续编程。当你把对于dataframe的操作代码调整好了之后,再写回原先的UDF。

这样的好处是:你能重新打开一个Ipython,然后交互式地进行编程,并且享受自动补全,文档查询等功能。对于python新手来说,有一个交互式的编程环境真的太重要了(毕竟作者也是一步一Bug的人)。所以这部分就是通过读写pkl的方式,帮大家找回了交互式编程环境。

代码式这样的:

@xw.func
@xw.arg('x', pd.DataFrame, index=2, header=1)
@xw.ret(index=True, expand='table')
def read_df(x, store=True):
    if store:
        x.to_pickle(path=r'YOUR_PATHdf.pkl')
	# 储存成pkl文件,在另外的Ipython中处理,形成成熟的处理方法后再写回这个函数中
    return

而调用该方法,储存下dataframe后,你只需要再IPython中调用下面的语句,就能够在交互式环境中重新获得这个dataframe了。

"另外的Ipython kernel"
df = pd.read_pickle(r'D:xlwingstest1df.pkl')

恰饭时间

文章绝对是作者原创,而且在资料不多的情况下探索新库真的很艰难。

如果您看到了这里,麻烦点赞并关注专栏,您的支持是对作者最大的认可~

本专栏后续后推出更多的表格数据预处理技巧文章,希望您能一直支持。

需要python入门资料,或者科学上网工具的作者请在点赞并关注专栏后,评论或者私聊作者获取相关资料。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值