你好,欢迎光临我的博客!

我是一名使用Python的程序员,这是我的github。平时喜欢玩各种电子游戏,这是我的psn:CenterRight这个博客用来分享我的生活、心得以及有关计算机的技术内容。除特殊说明外均采用CC0创作协议(任何人可以自由地复制,修改,分发和演出——甚至用于商业目的,而不必署名)但是转载建议保留原文链接以让读者看到最新的版本。本站所有内容仅代表本人观点,与我的雇主无关,并且会永远保持独立性不受任何组织和公司的影响。如果我们有共同兴趣,或者你遇到了麻烦,可以通过右边的电子邮箱联系我。也欢迎留言和订阅!

西红柿鸡蛋面加狮子头

欣 下午12:56
我 下午12:58
看起来真好吃
欣 下午1:00
多少钱
我 下午1:02
15
欣 下午1:02
7
我 下午1:03
哇塞
欣 下午1:03
番茄鸡蛋面5
欣 下午1:03
狮子头面6.5
欣 下午1:03
另加番茄鸡蛋2
欣 下午1:04
我点了番茄鸡蛋面5
欣 下午1:04
问加狮子头多少钱
我 下午1:04
这不是13.5?
欣 下午1:04
答2
欣 下午1:04
于是我加了狮子头
欣 下午1:04
花了5+2
我 下午1:04
哦我明白了
我 下午1:04
真厉害
欣 下午1:04
我觉得师傅是个傻子
我 下午1:04
研究生就是厉害
我 下午1:05
狮子头3.5
欣 下午1:05
同样的我说狮子头面加番茄鸡蛋就是8.5
我 下午1:05
哈哈哈
 

调教Mac外接显示器(开启Hdpi)

我的Mac外接的Dell U2515H显示器,总觉得很模糊,用的是2048*1152分辨率。觉得Mac只对外接显示器开开了这么几个分辨率很奇怪。

后来发现,原来按住option键点击“缩放”,可以开启隐藏的分辨率。

于是选择了1080P用了一段时间,还挺满意的。直到……某天看到了同事的屏幕,明明是和我一样的显示器,怎么会好这么多!

原来,还有个叫做Hdpi的东西。

简单来说,开启Hdpi和不开启的情况下,外接显示器截图如下(效果可以代表像素点数)。

不开启hdpi效果

开启hdpi效果

简直是两个世界!

Mac Hdpi开启方法

1. 关闭系统保护

具体操作是,重启电脑并按住Command+R,进入恢复模式,选择系统语言(仅仅会影响此次保护模式会话),然后选择工具(在最上面的bar)>终端。输入csrutil disable; reboot。更多参考这里

2. 覆盖显示器配置文件

发现一个很有用的项目,点击这里。可以生成显示器hdpi的设置文件。如果你和我一样用的显示器型号是DELL U2515H,可以直接下载DisplayProductID-*.plist文件然后执行sudo cp ~/Downloads/DisplayProductID-d06e.plist /System/Library/Displays/Contents/Resources/Overrides/DisplayVendorID-10ac/DisplayProductID-d06e(注意,如果你没有按照第一步关闭系统保护,那么即使加了sudo也会得到Operation Permitted),重启搞定。如果不是,就要参考这个页面自己config一下显示器的配置文件。

3. 设置显示器的分辨率

推荐使用RDM项目管理显示器的分辨率,可以从这里下载编译好的安装包。

RDM界面

推荐的分辨率是1920*1080.

关于第二步和第三步,不想这么麻烦可以直接使用SwitchResX这个软件,但是第一步是必须有的。虽然这个软件是收费的,但是听说可以无限试用。

另外,不知道是不是我的错觉,觉得开启之后显示器变得卡了一些。不过现实效果提升了一个档次。

 

奇葩网站吐槽第二弹

很久之前写过一篇《吐槽一些神奇的政府网站》,但是工作中(目前的工作是爬虫)碰到的奇葩网站远远不止这些,后来在那篇文章陆续更新了一些。但是考虑到修改文章不会发送rss feed,而且文章也被更新的越来越长,所以这里拆出来第二弹再发一次吧。而且我相信之后我会碰到更新这种奇葩网站的……估计不知道要写到第几弹。以下按照更新顺序贴出来,文章就不需要承上启下的润色了:


20170616更新:日了狗了,今天又碰到一个神奇的网站,比如某个详情页面如下:

本来是没有什么奇怪的,但是我把url拼起来之后一直是404,然后发现,如果把中文的部分encode两次,就和目标url一样了……日……


20170619更新:日了狗,今天写一个xpath怎么写都不对,看了看发出去的请求,好嘛,都到站外去了。找了半天,终于找到了罪魁祸首。我使用一个标签的id定位的,结果发现,相同id的html标签在这个页面下竟然有五个(没想到吧……像我这么屌的还有四个……)


170627更新:笑死我了,这个网站每次请求都会从相应收到一段cookies,然后就加到请求上去。不是修改,而是一直加一直加,访问几个页面之后,页面就会显示400Bad Request,cookies too big,哈哈哈哈。之前也碰到一个,是post请求不断增加字段,重复的字段越来越多,请求越来越大的…… 这,这应该叫做“饼干泄露”(内存泄露)吧,哈哈


170717更新:在post请求中传SQL语句的……


170802更新:今天要抓一个发布开庭公告的网站,打开一看,很整齐!很规则!很开心有没有!

一看源代码,人都傻了……


170802更新:日了够了,PM给我一个url,结果我发现已经打不开了,但是从主页是可以点进去的。研究了一下,发现这个url里面包含一个session id……

http://www.gzthfy.gov.cn/pa2/wel_3g.seam;jsessionid=04FF3DF586DE3D26555A210796A93B30.nod3?ggbh=91fa6f637dd947819df4c4b45878b514&cid=134752


170802更新:此站通过发送一个AJAX获取下一页的数据,我使用Python模拟发出一样的AJAX,企图在url或者post请求中找到与页码相关的信息改一下。发现此站翻任何一页发送的请求都是一样的!

一毛一样!Form一样、url一样,甚至连他喵的cookie都是一样!

观察一番,发现页码信息是记录在session里面的!也就是说,form里面的乱七八糟的数据(并不知道有什么用)只表示两种信息:往上翻,往下翻。当前你的位置,记录在服务器上(如此反人类,请问管理员你怎么把第二页的url发给你的上司呢?)

还有这种操作。

 

理解Python的UnboundLocalError

今天写代码碰到一个百思不得解为什么会出错的代码,简化如下:

意图很明显,首先我定义了一个全局的x,在函数中,如果有特殊需要,就重新重新赋值一下x,否则就使用全局的x。

可以这段代码在运行的时候抛出这个Error:

UnboundLocalError: local variable ‘a’ referenced before assignment

研究了一番,觉得挺有意思的。而且这是一个比较常见的问题,在Stack Overflow的Python tag下面基本上是个周经问题。


出现赋值就是局部变量!

基本的原理很简单,在Python FAQ中提到了:

在Python中,如果变量仅仅是被引用而没有被赋值过,那么默认被视作全局变量。如果一个变量在函数中被赋值过,那么就被视作局部变量。

重点强调一下,这里的被赋值过,指的是在函数体内任何地方被赋值过。无论是否会被执行到(比如在if语句中),甚至是变量引用之后再赋值(参考下面的代码),都被作为“被赋值过”,都变成了局部变量。

其实到这里这个问题的答案已经出来了,只要是在函数体内被赋值过,那么变量就是local的,任何赋值之前的操作都会出现一个RuntimeError。下面会深入解释一下。

赋值操作的编译过程(原理)

Python文档中有关赋值语句提到:

Assignment of an object to a single target is recursively defined as follows. If the target is an identifier (name):

  • If the name does not occur in a global statement in the current code block: the name is bound to the object in the current local namespace.
  • Otherwise: the name is bound to the object in the current global namespace.

就是说,如果赋值操作的变量没有用global声明,那么就将这个name绑定到局部名字空间,否则就绑定到全局名字空间。

我们可以使用symtable这个lib验证一下:

可以看到,x变量确实被绑定到了局部。使用dis库可以看到编译的代码:

其中,LOAD_FAST是从local的stack中读取变量名(LOAD_FAST对之后字节码的优化很重要)。由此可以看到,的确是在局部变量找x没有找到(前面并没有STORE_FAST操作),引发了UnboundLocalError。

所以我的理解是:Python编译建立抽象语法树的时候,根据语法书建立符号表,从语法书的函数体内决定符号是local的还是global(是否出现assignment语句),然后在编译其他语句生成字节码。

那么既然这样,为什么要等到运行的时候才报错,而不是编译的时候就报错呢?

参考下面的代码:

如果something_true(),x的赋值就会执行,那么代码不会抛异常。但是编译器并不会知道这个赋值语句会不会执行。换句话说,函数体内出现了赋值语句,但是Python编译过程无法得知赋值语句会不会执行到的。所以只要出现了赋值语句,就将变量视为局部。至于会不会出现未赋值就使用(UnboundLocalError),就运行看看了。

解决方法

前面已经提到了,显示地指定使用global就可以,这样即使出现赋值,也不会产生作为local的变量,而是去改变global的变量。

但是依然存在一个问题:

external的x既不是local,也不是global。这种情况应该使用Python3的nonlocal

参考资料

Understanding UnboundLocalError in Python

 

使命召唤全系列游戏汇总

整理了一下使命召唤所有的游戏,可以这么理解,使命召唤火起来的时候基本是从4(也就是现代战争开始),此后Activision(美国动视)每年发布一款游戏,手下有三个小组负责了现代战争、二战、黑色行动三个不同的支线,每年发布一款。所以基本上是间隔发布。这是理解整个使命召唤游戏剧情的基本,不然三条线穿插在一起都乱掉了。

作品序号
年份和开发小组
现代战争
二战
黑色行动 独立
1
2003年10月29日
使命召唤
2
2005年10月25日
使命召唤2
3
2006年11日7日
使命召唤3
4
2007年11月7日
Infinity Ward
5
2008年11月11日
Treyarch
6
2009年11月10日
Infinity Ward
使命召唤:现代战争2
7
2010年11月19日
Treyarch
8
2011年11月8日
Sledgehammer Games、Infinity Ward、Raven Software
9
2012年11月13日
Treyarch
10(登录ps4)
2013年11月5日
Infinity Ward、Raven Software、Neversoft
11
2014年11月4日
Sledgehammer Games
12
2015年11月6日
Treyarch
13
2016年11月4日
Infinity Ward
14
2017年11月3日
来源:维基百科