0%

原理

由于在Python2中字符串有两种类型strunicode,他们都是basestring的子类。

str类型,即是ascii字符或者经过encode的unicode,一个字符占用1byte。ascii码是美国信息交换标准代码,主要用于显示现代英语和其他西欧语言,用一个字节储存一个字符,所以ascii字符最多只有256(2^8)个。

而unicode包含了256个ascii码之外还包含其他各个国家的文字的编码,所以unicode的一个字符占用2个字节,这样理论上一共最多可以表示2^16(即65536)个字符,远大于256。

utf-8是unicode的一中实现,是unicode的一种编码方式。而且utf-8的编码方式,包含了ascii码的内容,也就是utf-8兼容ascii。

打个比方,unicode是商品,utf-8就是打包好的一个个包裹(encode),打包是为了传输和储存的方便。而不同的编码之间不能直接互相转换,都需要转成unicode,也就是decode。

所以碰到一个str,你就得明白它是encode过的,你得调用相应的decode方法才不会乱码。

python2解释器的默认编码方式是ascii,如果我们给系统的输入是非ascii编码的字符,系统在尝试解码时就会出现UnicodeDecodeError

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> s = '2'
>>> u = u'2'
>>> type(s)
<type 'str'>
>>> type(u)
<type 'unicode'>
>>> issubclass(str,basestring)
>>> issubclass(unicode,basestring)
True
>>> '啊'.decode('ascii')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)

几种解决方法

阅读全文 »

以vmware虚拟机为例

设置IP

运行 sudo nano /etc/network/interfaces
将文件修改成如下:

1
2
3
4
5
auto eth0  # eth0是网卡名称,你的不一定是这个,可通过ifconfig查看
iface eth0 inet static
address 192.168.157.129 # 地址
gateway 192.168.157.2 # 网关
netmask 255.255.255.0 # 掩码

修改DNS

运行 sudo nano /etc/resolvconf/resolv.conf.d/base
把文件改成 nameserver 192.168.157.2
192.168.157.2改成你需要的dns,这里因为是vmware的NAT模式,所以dns和网关是一样的。

概述

如果一个在函数中存在yield关键字,那么这个函数就构成了生成器。生成器是一个函数,它生成一个序列,以便在迭代中使用。
调用这个函数,并不会马上开始执行函数体中的代码,而是返回一个生成器对象,通过调用生成器对象的next()方法(python3中是__netx__())执行函数。

那么,具体的函数中语句的执行顺序是怎么样的呢?

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def func(x=10):
print 'the beginning of function'
if x <= 0 or not isinstance(x, int):
return
for i in range(x):
print 'before yield', i
yield i
print 'after yield', i

gen = func(2)
print '*'*20
print '-> yielding: %s' % gen.next()
print '*'*20
print '-> yielding: %s' % gen.next()
print '*'*20
print '-> yielding: %s' % gen.next()

输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
********************
the beginning of function
before yield 0
-> yielding: 0
********************
after yield 0
before yield 1
-> yielding: 1
********************
after yield 1
Traceback (most recent call last):
File "D:\Projects\test.py", line 28, in <module>
print '-> yielding: %s' % gen.next()
StopIteration

分析

  1. 首先运行func(2),这时函数的所有语句都没有执行,返回一个生成器赋值给gen
  2. 第一次执行gen.next(),函数从头开始执行,运行完yield语句暂停住了。
  3. 再次运行gen.next(),从停下的地方继续,直到遇到遇到下一个yield,运行完yield语句又暂停住了。
  4. 第三次尝试运行gen.next(),运行完print 'after yield', i,由于循环次数已满,找不到下一个yield,就出现StopIteration错误

需求

由于最近做Python的linux服务器脚本,经常要同步代码到测试服务器,又不想直接ssh登录到服务器,所以萌生了用git自动同步代码的想法。
具体的要求是:测试机是服务器,需要本地一push代码,测试机能实时更新。
查阅相关资料发现可以用git的hooks来实现。

阅读全文 »

设置root密码

运行 sudo passwd
根据提示输入root帐户密码。

修改lightdm配置文件

运行 ls /usr/share/lightdm/lightdm.conf.d/ -al
-rw-r–r– 1 root root 72 12月 3 03:57 50-greeter-wrapper.conf
-rw-r–r– 1 root root 68 12月 3 03:57 50-guest-wrapper.conf
-rw-r–r– 1 root root 51 12月 3 03:57 50-xserver-command.conf
-rw-r–r– 1 root root 118 4月 16 17:08 60-lightdm-gtk-greeter.conf

就是greeter这个文件,不同的发行版可能名字不同。
运行 sudo gedit /usr/share/lightdm/lightdm.conf.d/60-lightdm-gtk-greeter.conf
改完以后是这样

1
2
3
4
5
[SeatDefaults]
autologin-user=root
greeter-session=lightdm-gtk-greeter
greeter-show-manual-login=true
all-guest=false

修改 /root/.profile

在刚修改完root权限自动登录后,发现可能开机出现以下提示:

1
2
3
Error found when loading /root/.profile
stdin:is not a tty
…………

运行 gedit /root/.profile
打开文件后找到mesg n,将其更改为tty -s && mesg n

引子

童话里经常会看到英雄打败恶人的故事,而且故事里总会有一个类似黑暗森林的场景——要么是一个山洞,要么是一篇森林,要么是另一个星球,反正是英雄不该去的某个地方。
当然,一旦反面角色在剧情中出现,你就会发现英雄非得去那片破森林去杀掉坏人。当英雄的总是不得不冒着生命危险进到邪恶森林中去。

在面向对象编程中,“继承”就是那片邪恶森林。
有经验的程序员知道如何躲开这个恶魔,因为他们知道,在丛林深处的“继承”,其实是邪恶女皇“多重继承”。她喜欢用自己的巨口尖牙吃掉程序员和软件,咀嚼这些堕落者的血肉。
不过这片丛林的吸引力是如此的强大,几乎每一个程序员都会进去探险,梦想着提着邪恶女皇的头颅走出丛林,从而声称自己是真正的程序员。你就是无法阻止丛林的魔力,于是你深入其中,而等你冒险结束,九死一生之后,你唯一学到的,就是远远躲开这片破森林,而如果你不得不再进去一次,你会带一支军队。

有的程序员现在正在丛林里跟邪恶女皇作战,他会对你说你必须进到森林里去。他们这样说其实是因为他们需要你的帮助,因为他们已经无法承受他们自己创建的东西了。

而对于你来说,你只要记住这一条:
大部分使用继承的场合都可以用合成取代,而多级继承则需要不惜一切地避免之。

阅读全文 »

番茄工作法简介

番茄工作法(英语:Pomodoro Technique)是一种时间管理法方法,在上世纪八十年代由Francesco Cirillo创立。 该方法使用一个定时器来分割出一个一般为25分钟的工作时间和5分钟的休息时间,而那些时间段被称为pomodori,为意大利语单词 pomodoro(中文:番茄)之复数。

番茄工作法有五个基本步骤:

  1. 决定待完成的任务
  2. 设定番茄工作法定时器至 n 分钟(通常为25分钟)。
  3. 持续工作直至定时器提示,记下一个x。
  4. 短暂休息3-5分钟。
  5. 每四个x,休息15-30分钟。

番茄工作法的关键是规划,追踪,记录,处理,以及可视化。在规划阶段,任务被根据优先级排入”To Do Today” list。 这允许用户预计每个任务的工作量。当每个番茄时结束后,成果会被记录下来以提高参与者的成就感并为未来的自我观察和改进提供原始数据。

番茄工作法一般与GTD相结合,能取得事半功倍的效果。

工具推荐

  1. GTD软件,用于任务规划和记录,推荐滴答清单Doit.im
  2. 小米手环,震动提醒防止打扰别人。
  3. 米环工具 Mi Band Tools, 百度网盘: https://pan.baidu.com/s/1qZ54Rr2 密码: pcqh
  4. 极简番茄, 百度网盘: https://pan.baidu.com/s/1smZUZxj 密码: 8fff

小米手环本来没有番茄钟的功能,通过Mi Band Tools极简番茄这两个应用,在米环工具的“应用”中添加 极简番茄,可以实现手环震动提醒番茄钟。
当然你也可以直接使用极简番茄,通过手机震动或是响铃提醒,或者买一个计时器。

小米手环和极简番茄结合方法

在米环工具的“应用”中添加 极简番茄。

具体的应用配置可以参考截图,一般只修改震动次数、忽略不可清除的通知,其他默认即可



git 简介

git是一个分散式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)創作,於2005年以GPL釋出。最初目的是为更好地管理Linux内核开发而设计。
初始版本由Linus大神在两个星期内写出来,之后基本一统文件版本控制的天下。

名词解释

工作区:就是你在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在”git目录”下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
branch:分支,相当于不同的平行世界
remote:远程仓库
origin:默认的远程仓库名词
HEAD:一个指向当前版本号的指针

阅读全文 »

冒泡排序 BubbleSort

介绍

遍历序列,比较两个元素,如果前面的大于后面的就交换两者的位置。其实称之为冒泡排序不如加沉底排序,因为每一轮比较,这一轮轮最大都会被排到序列末尾,其实沉底更为贴切。

步骤

  1. 遍历序列,比较序列的相邻元素,比较n-1次,如果前面的大于后面的就交换两者的位置。
  2. 比较次数减一,重复步骤1
  3. 共遍历n-1次

代码

  1. 原始版本

    1
    2
    3
    4
    5
    6
    7
    8
    def bubble_sort(arry):
    n = len(arry)
    while n > 1:
    n -= 1
    for x in range(n):
    if arry[x] > arry[x+1]:
    arry[x], arry[x+1] = arry[x+1], arry[x]
    return arry
  2. 改进版本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def bubble_sort(arry):
    n = len(arry)
    while n > 1:
    n -= 1
    swap_flag = False # 增加一个标记,当排好序后直接退出
    for x in range(n):
    if arry[x] > arry[x+1]:
    arry[x], arry[x+1] = arry[x+1], arry[x]
    swap_flag = True
    if not swap_flag:
    break
    return arry
阅读全文 »

说到python赋值语句,大家想必一个念头——so easy,不是lz = 'dashabi'吗。
确实,easy是easy,里面却有个小坑,虽小,却不易发现。在代码量多的时候,就有点恶心了。

正常的语句是这样

1
2
3
>>> aa = u'这是一个坑'
>>> aa
u'\u8fd9\u662f\u4e00\u4e2a\u5751'

坑在这里

1
2
3
>>> aa = u'这是一个坑',
>>> aa
(u'\u8fd9\u662f\u4e00\u4e2a\u5751',)

看出区别没有,坑的后面有个逗号,平时这逗号没什么卵用,但在赋值语句的末尾会将原来的对象转化为tuple。
aa = (u'这是一个坑',)是一样的效果。

总结

  1. Python2 中使用from __future__ import division就可以使用python3的除法。
  2. Python2 中/与操作数有关,x / y中x、y都为整型的话,为floor除法,否则为true除法也是日常的除法。
  3. Python3 中/true除法, 与操作数无关。
  4. //在 Python2 与 Python3 中并无差别, 都代表floor除法

Python3

1
2
3
4
5
6
7
8
>>> -5/3
-1.6666666666666667
>>> -5//3
-2
>>> -5.0/3
-1.6666666666666667
>>> -5.0//3
-2.0

Python2

1
2
3
4
5
6
7
8
>>> -5/3
-2
>>> -5//3
-2
>>> -5.0/3
-1.6666666666666667
>>> -5.0//3
-2.0

简介

谷歌百度一键搜索, 在百度页面上搜谷歌,在谷歌的页面上搜索百度,无需切换,无需重新输入搜索词。

详细描述:
虽然谷歌比较好用,结果也准确,但搜索中文这方面却也弱了点,百度还是有点用。谷歌百度一键搜索, 在谷歌的页面上搜索百度,在百度页面上搜谷歌,无需切换,无需重新输入搜索词。
目前支持http(s)://www.baidu.com, http(s)://www.google.com.hk, http(s)://www.google.com

创建:2015.11.25
作者:ponder.work
forked from: raywill/BaiGoogleDu

阅读全文 »

概述

在开发django网站时发现,用户登录后不能跳转到之前的页面,google了很多答案,讲得也不清楚。

其实就是渲染登陆表单时,将原链接带到action参数里,view函数接收到参数后进行重定向。

实现

登录链接

1
<a href="/account/login/?next={{request.path}}">登录</a>

view

1
2
3
4
5
6
7
8
def login(request):
next_url = request.REQUEST.get('next', '/')

if request.method == 'GET':
return render_to_response('account/login.html', {'next_url': next_url}, context_instance=RequestContext(request))

django_login(request, user)
return redirect(next_url)

登录表单

1
2
3
4
5
6
7
<form action="/account/login/?next={{next_url}}" method="post" >
{% csrf_token %}
用户名<input id="username" type="text" name="username" required/>
</br>
密码<input type="password" name="password" required/>
<input type="submit" value="登 录"/>
</form>

问题背景

在用django的admin进行管理的时候,对于指定的用户角色,不希望他看到特定状态的foreignkey,可以采用以下方案。

当然,也可通过自定义form解决该问题。

解决方案

1
2
3
4
5
6
7
8
9
10
11
12
class FactoryOrderItemInline(admin.TabularInline):
model = FactoryOrderItem
fields = ('order_item', 'product_sn', 'style', 'size', 'factory_sn', 'price', 'quantity', 'amount')
extra = 1

def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'order_item':
try:
parent_obj_id = request.resolver_match.args[0]
except IndexError: #仅在新建状态过滤
kwargs['queryset'] = OrderItem.objects.filter(order__status='2')
return super(FactoryOrderItemInline, self).formfield_for_foreignkey(db_field, request, **kwargs)


  下午去看了《小王子》电影,拍得很好,在忠实原著的基础上又有所发展。回来又把原著给温习了一遍,感触颇深。
  
  记得李安在拍《卧虎藏龙》的时候说过每个人心中都有把青冥剑,而我想说每个人心中都有个小王子
  作者说过,这是写给曾经是孩子的成人的童话。所以,不论文章还是电影,都比较有深度,适合我们这些曾经是孩子的人观看。

阅读全文 »