开始学习Python

最近由于工作要求,需要学习下Python,以前只是简单的照猫画虎写过一点点Python,深入的还不太了解。

环境搭建

环境

  • OS: Mac
  • Emacs(spacemacs) in Terminal
  • /opt/local/bin/python version2.7 installed by MacPorts
  • /opt/local/bin/pip installed by MacPorts

搭建

安装python

虽然mac下自带了python,但是习惯了用MacPorts安装软件,所以一般mac自带的python我都不用。

sudo port install py27
sudo select --set python python27
sudo port install py-pip
sudo select --set pip pip27

Spacemacs

spacemacs 这套配置自带了python的开发layer,这里需要配置一下Python shell的可执行文件路径:

(setq python-shell-interpreter "/opt/local/bin/python")

我用的是Emacs C/S 模式,启动了一个Emacs Server

Alias :

# start emacsclient
alias e="emacsclient -t -a ''"
# kill emacs server
alias ek="emacsclient -e '(kill-emacs)'"

打开测试python文件

e test.py

按下",si" 或者M-x python-start-or-switch-repl,启动一个repl

选中test.py 中的一行 M-x python-shell-send-region,将所选内容发送给python repl执行. 快捷键为",sr"

在python-mode下",s" 开头的绑定了python-shell-send- 开头的函数,具体使用可自行测试。

然后可以用REPL的方式来学习Python,关于Emacs REPL方式的使用,请参考这个视频Hacking Emacs REPL(可能需要翻墙)。还有知乎的相关连接:编程术语REPL的正式翻译是什么?

多说无用,上图: gif_emacs_python_repl.gif

解释:

打开emacs,两个buffer,一个buffer 是 test.py ,用来写python代码,另一个buffer是python shell,用于接收从test.py 发送过去的内容。python shell buffer当然也能交互,直接写python代码

Emacs Ycmd 报错解决

ymcd配置:

(set-variable 'ycmd-server-command (list "/opt/local/bin/python" (expand-file-name "Documents/github/ycmd/ycmd" "~/")))
(add-hook 'c++-mode-hook 'ycmd-mode)

启动一个cpp buffer的时候,调用global-ycmd-mode ,发生下面的错误

# Fatal Python error: PyThreadState_Get: no current thread
# Process ycmd-server abort trap: 6

经google,这是由于python version导致的

sudo port select --list python
# Available versions for python
# no
# python26-apple
# python27 (active)
# python27-apple
sudo port select --set python python27-apple

这样之后就没有问题了

fileinput module in-place replacement

python 替换文件内容,类似与sed处理流程的一个模块

  import fileinput
  import os
  import sys

  filename = "/Users/xxx/test.txt"
  for line in fileinput.input(filename, inplace=True):
	  if line.find("commonplist.png") > -1:
		  newContent = line.replace("commonplist.png", "hehe.png")
		  sys.stdout.write(newContent) 
	  else:
		  sys.stdout.write(line)

# 这里有个注意的地方,如果要替换掉某一行,不要用print,因为print会加一个默认的换行
# 应该用sys.stdout.write(newContentAfterReplace)