有些人以为生活只有诗与远方,后来他离开了生活。
有些人以为生活只是眼前的苟且,后来他失去了自我。
人生在世,无论理想如何远大,终须为稻粱谋。陶渊明不为五斗米折腰,前提没这点俸禄也不至于饿死。若是形式迫人,虽嗟来之食亦受之。一旦不为生计发愁,迎接你的必是诗与远方。故我先欲求之财务自由,后践吾心之所向。
不够强大的理想主义者,一大部分矮化成了现实主义者,另一部分成了随波逐流的躯壳,余下的抛弃了这个娑婆世界。
而我,先欲求安身立命之所,后追寻最初的梦想,希望能走得更远。
人类一思考,上帝就发笑。
对于初学者来说,python的类变量(也就是java中的静态变量)和实例变量(也就是属性)有一些很容易混淆的地方,同时对这些特性深入了解有助于理解python的面向对象思想。
1 | >>> class ClassA(object): # 1 |
ClassA
类,它有一个类变量num1
,还有一个实例变量num2
。 a1.num1
的时候,实际上是引用类变量num1,因此a1.num1 is ClassA.num1
值为True
。 a1.num1 = 3
的时候,其实给a1绑定了一个属性num1,这是动态语言的特性,此时a1.num1 is ClassA.num1
值为False
。a1.num1
的时候,先是在a1自己的命名空间内查找num1,没找到就在所属类的命名空间找,还没有就抛出AttributeError: 'ClassA' object has no attribute 'num3'
.a1.num1 = 3
之后,a1自己的命名空间内找到了num1,就不继续往上查找了。a1.__class__.num1
来访问。以上这些,也适用于staticmethod
和classmethod
。
凡是条件好一点的图书馆,只要工作人员不禁止,必定有一部分座位因占座党而闲置。
举我最近去的广州图书馆为例,我早上9点开始自习,到下午5点,占座的人始终没来,而且不是一两次。几乎每次有占座的,很大可能一天都不来。
这也很好理解,既然需要占座自然是来的意愿不是很强,不来自然是情理之中。人皆有惰性,无可厚非,但座位有限,还是留给需要的人为好。
除占座党之外,手机党和电脑党也是图书馆一大特色,并且与年龄无关。
今天坐我对面的是个大概60岁的大爷,先是早上来没找到位置坐,把我对面的占座党呵斥了一通,抢了她占的座位。然后等我下午从图书馆出来时,他手上拿的手机还没有放下。既然玩手机,在家里不是更舒服吗,何必呢?学得下就学,不行就回去休息,在这磨洋工除了求个心安之外毫无裨益。
另外,品行、习惯与年龄没多大关系,不好的不改正,年纪大了还是不好,不过是习惯了而已。俗语说三岁看老
,未免夸张了点,十三、二十三看老估计是十拿九稳。
人呐,还是要对自己有所要求,若是随着年岁的增长而没有丝毫长进,多么可悲,多么可怕。年少时不学好有人教育你,年老了还无长进,无需教育也无人可教育你了。
在卫生间,洗完手,有一人擦手用了接近2米的纸,很大一堆,不知道什么心态。如果你平时在家都是这样使用,我无话可说,但仅因为免费就滥用,未免太下作了。
免费的东西并不是没有成本,而是一些心存善念的人承担了,因此我们在使用它的时候因心存感激。
一切免费的物品,如图书馆的座位,如纸巾,如果不能在使用价值或者获取代价上和通常物品加以区分,就不免会被滥用,导致真正需要的人不能得到。
而这正是这个世界的可悲之处,所有事物并不是让需要的人得到,而是让有取得优势的人得到。
re是python中的正则表达式处理模块,本文是为了总结re模块的用法。
至于正则表达式的写法可以看正则表达式30分钟入门教程
re.complie(pattern, flags=0)
把正则编译为_sre.SRE_Pattern object
对象,在多次匹配的时候可提高运行效率。1
2
3
4
5
6
7
8
9>>> pattern = re.compile(r'\w(o)')
>>> pattern.match('doooo')
<_sre.SRE_Match object at 0x7f45fc3d9990>
>>> pattern.match('doooo').group(1)
'o'
>>> re.match(r'\w(o)', 'doooo')
<_sre.SRE_Match object at 0x7f45ec0be0a8>
>>> re.match(r'\w(o)', 'doooo').group(1)
'o'
顾名思义,所谓装饰器就是对原有的对象做一些装饰,也就是给已有的对象添加一些功能。
假如我现在想在函数运行时输出一些信息
1 | def running(func): |
输出1
2`my_sum` is running...
I cat't sum right now!
要使用装饰器,先得定义一个装饰器函数,然后在需要装饰的函数的前一行使用@
符号加上装饰器名称
。
在这里的效果等效于running(my_sum)(),不过看起来有点别扭。
注意:一旦通过@running
装饰了函数,不管被装饰函数是否运行,python解释器都会执行一遍running
函数。
上一个装饰器用起来还行,但是有一个致命的问题,它不能装饰带参数的函数。所以我们在装饰器内部定义_wrapper
函数,并返回它。这个函数接收所有位置参数*args
,和关键字参数*kwargs
,在_wrapper
内部执行func(*args, **kwargs)
。
1 | taskman |
上面的例子是一个Django项目,Python包的导入都是相对于主程序
来说的。
这个项目的主程序就是manage.py
,跟manage.py同级的文件夹(含有__init__.py
)如task
,man
就称之为包,若同级有文件就称之为顶级模块。
在这个项目里所有Python包的导入,都应该写完整路径, 或者使用相对当前文件的相对路径。
例如在文件taskman/task/views.py
中,想要导入taskman/man/setting.py
,就得这样。1
2
3
4## 绝对路径 import
from man.setting import some_setting
# or
from man import setting
再例如, 在文件taskman/task/views.py
中,想要导入taskman/task/urls.py
,就得这样。1
2
3
4
5
6
7
8## 绝对路径 import
from task.urls import some_setting
# 或者
from task import urls
## 相对路径import
from .urls import some_setting
from . import urls
ValueError: Attempted relative import in non-package
由于在Python2中字符串有两种类型str
和unicode
,他们都是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 | >>> s = '2' |
以vmware虚拟机为例
运行 sudo nano /etc/network/interfaces
将文件修改成如下:1
2
3
4
5auto eth0 # eth0是网卡名称,你的不一定是这个,可通过ifconfig查看
iface eth0 inet static
address 192.168.157.129 # 地址
gateway 192.168.157.2 # 网关
netmask 255.255.255.0 # 掩码
运行 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 | def func(x=10): |
输出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
func(2)
,这时函数的所有语句都没有执行,返回一个生成器赋值给gen
。gen.next()
,函数从头开始执行,运行完yield语句暂停住了。gen.next()
,从停下的地方继续,直到遇到遇到下一个yield,运行完yield语句又暂停住了。gen.next()
,运行完print 'after yield', i
,由于循环次数已满,找不到下一个yield,就出现StopIteration
错误运行 sudo passwd
根据提示输入root帐户密码。
运行 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 | Error found when loading /root/.profile |
运行 gedit /root/.profile
打开文件后找到mesg n
,将其更改为tty -s && mesg n
。
童话里经常会看到英雄打败恶人的故事,而且故事里总会有一个类似黑暗森林的场景——要么是一个山洞,要么是一篇森林,要么是另一个星球,反正是英雄不该去的某个地方。
当然,一旦反面角色在剧情中出现,你就会发现英雄非得去那片破森林去杀掉坏人。当英雄的总是不得不冒着生命危险进到邪恶森林中去。
在面向对象编程中,“继承”就是那片邪恶森林。
有经验的程序员知道如何躲开这个恶魔,因为他们知道,在丛林深处的“继承”,其实是邪恶女皇“多重继承”。她喜欢用自己的巨口尖牙吃掉程序员和软件,咀嚼这些堕落者的血肉。
不过这片丛林的吸引力是如此的强大,几乎每一个程序员都会进去探险,梦想着提着邪恶女皇的头颅走出丛林,从而声称自己是真正的程序员。你就是无法阻止丛林的魔力,于是你深入其中,而等你冒险结束,九死一生之后,你唯一学到的,就是远远躲开这片破森林,而如果你不得不再进去一次,你会带一支军队。
有的程序员现在正在丛林里跟邪恶女皇作战,他会对你说你必须进到森林里去。他们这样说其实是因为他们需要你的帮助,因为他们已经无法承受他们自己创建的东西了。
而对于你来说,你只要记住这一条:
大部分使用继承的场合都可以用合成取代,而多级继承则需要不惜一切地避免之。
番茄工作法(英语:Pomodoro Technique)是一种时间管理法方法,在上世纪八十年代由Francesco Cirillo创立。 该方法使用一个定时器来分割出一个一般为25分钟的工作时间和5分钟的休息时间,而那些时间段被称为pomodori,为意大利语单词 pomodoro(中文:番茄)之复数。
番茄工作法有五个基本步骤:
番茄工作法的关键是规划,追踪,记录,处理,以及可视化。在规划阶段,任务被根据优先级排入”To Do Today” list。 这允许用户预计每个任务的工作量。当每个番茄时结束后,成果会被记录下来以提高参与者的成就感并为未来的自我观察和改进提供原始数据。
番茄工作法一般与GTD
相结合,能取得事半功倍的效果。
滴答清单
或Doit.im
小米手环本来没有番茄钟的功能,通过Mi Band Tools
和极简番茄
这两个应用,在米环工具的“应用”中添加 极简番茄,可以实现手环震动提醒番茄钟。
当然你也可以直接使用极简番茄
,通过手机震动或是响铃提醒,或者买一个计时器。
在米环工具的“应用”中添加 极简番茄。
具体的应用配置可以参考截图,一般只修改震动次数、忽略不可清除的通知,其他默认即可
git是一个分散式版本控制软件,最初由林纳斯·托瓦兹(Linus Torvalds)創作,於2005年以GPL釋出。最初目的是为更好地管理Linux内核开发而设计。
初始版本由Linus大神在两个星期内写出来,之后基本一统文件版本控制的天下。
工作区:就是你在电脑里能看到的目录。
暂存区:英文叫stage, 或index。一般存放在”git目录”下的index文件(.git/index)中,所以我们把暂存区有时也叫作索引(index)。
版本库:工作区有一个隐藏目录.git,这个不算工作区,而是Git的版本库。
branch:分支,相当于不同的平行世界
remote:远程仓库
origin:默认的远程仓库名词
HEAD:一个指向当前版本号的指针
遍历序列,比较两个元素,如果前面的大于后面的就交换两者的位置。其实称之为冒泡排序不如加沉底排序,因为每一轮比较,这一轮轮最大都会被排到序列末尾,其实沉底更为贴切。
原始版本
1 | def bubble_sort(arry): |
改进版本
1 | def bubble_sort(arry): |