python

remote debugger

你没有看错,Python Remote Debugger with PyCharm!本文是基于Python IDE:PyCharm,主要介绍 Remote Debugger 的在 PyCharm 中的配置使用,本文希望传递一个消息,远程是可在IDE调试的,也希望大家能在以后的工作中调试起来…。

Debug Configurations

先上图:
Debug Configurations

  • 1: 这是一个django服务的示例
  • 2: 选择的是服务器(Remote)运行环境interpreter
  • 3: 本地和远端path mapping

SSH

SSH最基本的通讯协议,服务器和测试服务器没有不开的吧。

Remote Interpreter

Interpreter 解释器,使用python的对虚拟环境virtualenv应该都不陌生,我们首先需要一个和服务器一样的运行环境。
Setting add Interpreter
按照顺序操作到4,点击Add Remote(如下图),SSH配置完点OK。
Configure Remote Python Interpreter
初次连接可能弹出提醒,确认即可,然后会回到设置主界面,切记点击ApplyOK

config mapping etc

Configure Server
单击向下的那个箭头,然后编辑配置,就回到了最开始那个图,配置好后用debug方式启动就可以远程调试了,吼吼

Linux

远程调试已经完了,你可以很方便的在你本地以调试方式启动服务,在本地设置断点,然后使用服务器ip访问,捕获到断点是不成问题的,修改代码,PyCharm 也有同步的功能,但我还是喜欢下面的~

sshfs

Linux,所以直接挂载测试服务器文件:
$ sshfs -o idmap=user root@10.65.200.151:/opt/disk2/var/www/V6.3.1 /local/mount/point
直接将服务器目录挂载到本地,实质就一份文件。(避免和线上配置可能的冲突)
附:取消挂载的命令$ fusermount -u $point

Windows

感谢永哥,在windows下实现了,给大家扫雷了。在用户目录下新建.ssh文件夹和known_hosts文件,不然远程环境会无法建立。
虽然用不了sshfs,但是可以sftp的,配置远程文件时,需要明确选下如图,虽然选后路径不变:
Remote Host File
不选的话,远程文件可能不识别,识别后远程文件显示为绿色。

总结

本文希望能传递一个消息:远程是可调试的!希望大家以后能用起来,以后如何用好还请大家思考。最后,欢迎任何反馈。

django advanced

本文记述我在使用Django时遇到的两个问题,两次被坑的过程,也是两次进步的过程。

qs[m:n].update()

业务我就不多说了,给queryset(总数可能有十万之多)中的部分(以万记)更新某个字段(或者说分配到某个订单),由于要保证互斥,同时希望序列号连续(对应实体的东西,方便分取)所以使用select_for_update(),当然任何使用锁的地方应该确保尽可能少锁,同时尽快释放。

问题出来了,如此多的数据,如果循环更新,锁的时间将会比较长,可是Django不支持切片后更新。办法:

qs[m:n].update()
1
2
3
qs = Models.objects.filter(...).select_for_update().order_by("id")
rows = qs.filter(id__lt=qs[count:count+1].get().id).update(...)
assert(rows == count) # TODO: remove

qs.distinct().aggregate()

相信熟悉SQL的同学对distinct一定不陌生,加上MySQL后端,就出了这个问题。由于冗余条件的存在,所以qs里面出现了重复数据,这里就不赘述了。(注:当时使用的是Django==1.5.8,django不支持distinct(field)) So:

qs.distinct().aggregate()
1
2
3
qs = Models.objects.filter(...)
qs = Models.objects.filter(pk__in=qs) # distinct
sum_dict = qs.aggregate(...)

没错,就是多操作了一步。解决方法就是这么简单,可是这个重复数据并不总是有,让我头疼了好一阵子,不过还是被我给揪出来了。

总结

第二个问题环境:MySQL数据库后端 + Diango<1.6。当然如今我们都升1.7了,不过我还是记录下。

slice

“不会slice,绝不能说会python”,slice的重要性不言而喻。

Basis

  • index start with 0
  • support negtive index
  • [included:excluded:step] eg: [:], [::-1]
  • work with list, tuple and string

step

Ipython 中的示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
In [1]: e = range(6)

In [2]: e
Out[2]: [0, 1, 2, 3, 4, 5]

In [3]: e[:]
Out[3]: [0, 1, 2, 3, 4, 5]

In [4]: e[6]
IndexError

In [5]: e[5]
Out[5]: 5

In [6]: e[:5]
Out[6]: [0, 1, 2, 3, 4]

In [7]: e[:6]
Out[7]: [0, 1, 2, 3, 4, 5]

In [8]: e[::-1]
Out[8]: [5, 4, 3, 2, 1, 0]

In [9]: e[6:0]
Out[9]: []

In [10]: e[6:0:-1]
Out[10]: [5, 4, 3, 2, 1]

In [11]: 0 in e[6:0:-1]
Out[11]: False

In [12]: e[5:0:-1]
Out[12]: [5, 4, 3, 2, 1]

In [13]: e[5:0:-1] == e[6:0:-1]
Out[13]: True

In [14]: e[-1:-7:-1]
Out[14]: [5, 4, 3, 2, 1, 0]

In [15]: e[-1:-7:-1] == e[::-1]
Out[15]: True

In [16]: e[-1:-9:-1]
Out[16]: [5, 4, 3, 2, 1, 0]

In [17]: e[::-2] == e[-1:-7:-2]
Out[17]: True

In [18]: e[::-2] == e[-1:-8:-2]
Out[18]: 'Just do IT'
  • e[::-1] == e[-1:-7:-1]
  • slice切片中索引可以超出实际范围
  • 带有步长的切片,索引顺序和步长方向一致
  • 切片总是新产生一个对象,而不是改变原有对象

总结

Just do IT

tuple change?

在python中元组tuple是不能改变的,列表和字典是可以改变的。

change

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In [1]: l = [1, 2]

In [2]: d = {'a':'aaa', 'b':'bbb'}

In [4]: t = (l, d)

In [5]: t
Out[5]: ([1, 2], {'a': 'aaa', 'b': 'bbb'})

In [7]: l.pop()
Out[7]: 2

In [8]: t
Out[8]: ([1], {'a': 'aaa', 'b': 'bbb'})

In [9]: l.append(3)

In [10]: t
Out[10]: ([1, 3], {'a': 'aaa', 'b': 'bbb'})

总结

上述,元组的项目是列表,改变了列表。元组有没有改变,自己掂量吧…

4>3>2

在我看来,python不仅是程序,还是艺术。

4>3>2

1
2
In [1]: 4>3>2
Out[1]: True

懂程序的都知道,4>3 and 3>2不能写成4>3>2(4>3求值后是True,也就是1)。可是他们不懂python,4>3>2学过数学的都知道,对的就是对的啊。python推荐这么写,这么写效率更好。

and & or

Python 的bool运算 and & or,但运算结果不是单纯的False或者True,无疑结果是对的。一句话总结:用最少的运算,保留更多的信息,保证正确的结果。

Documentation

Operation Result Notes
x or y if x is false, then y, else x 运算是短路的
x and y if x is false, then x, else y 运算是短路的

关于短路

print None and None[0]没有报错,正常打印出None。(None[0]会报TypeError错)

bool ? x : y运算

由于python的bool运算保留了更多信息,所以可以实现上述三目运算。

三目运算

三目运算是这样的,可是存在一个误区!
bool and x or y

误区,当x为假时,永远返回y。

修正上述误区:((test and [x]) or [y])[0]采用了x为假时,[x]为真(避免上述误区),然后[0]索引求值。

还有种简洁的写法:(y, x)[bool] 其中x,y是反的,用bool索引求值。

上面涉及了两个值,网上还有三个或更多值的,我就不多少了,也不建议去搜。ugly

技巧VS陷阱

我认为,这个既算不上技巧,也不能称为陷阱。

python实现三目运算还是用x if bool else y,从看着到结果都比较顺眼。当然适当的使用and & or保留值的特性也是可以的,主要是你要明白你写的是什么。

写代码,自己要明白,还要让看的人明白。

(看的人也要知道自己看的是python)