Python中被引入模块(module)中属性(attribute)和全局变量的命名空间问题

在之前的一篇博客「Django(Python)中按屏幕显示宽度截取字符串」中,我写了一个用来获取字符串在屏幕上显示宽度的函数get_screen_width(*args, **kwargs),这个函数放在一个utility.py文件中,在项目的其它文件中要使用这个函数时,可以通过这样的方式来使用它:

import utility
screen_width = utility.get_screen_width(input_str)
这是Python中很常见的场景,但是使用这个函数的时候我还是产生了一些困惑。

get_screen_width这个函数使用了一个定义在utility.py中的全局变量WIDTHS,问题就在于:

当我在其它文件中引入get_screen_width()并调用时,函数对WIDTHS这个全局变量的使用能否正常工作?

当时我简单地测试一下后没问题就没有多想。今天在翻看Python文档的时候看到一段话:

Strictly speaking, references to names in modules are attribute references: in the expression modname.funcname, modname is a module object and funcname is an attribute of it. In this case there happens to be a straightforward mapping between the module’s attributes and the global names defined in the module: they share the same namespace!

...

It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called.1


这里明确说了两点:

  • module.funcname和module中的全局变量共享同一个命名空间
  • 对定义在模块中的函数来说,“全局空间”指的是其所在模块的命名空间,不管从哪里或者什么别名来调用这个函数
——这两点似乎就是对上面这个疑问的明确回答,不知道想的对不对。

让Django的URL对大小写不敏感

Django的URL配置是大小写敏感的,不过有的时候并不希望这样,比如刚才在添加本站的RSS功能的时候,希望/rss//RSS/都能读取本站的RssFeed。

解决办法很简单,只要在URL配置中的匹配表达式最前面加上(?i)即可,

例如:

url(r'(?i)^rss/$', rss.PostsByAdminFeed(), name='rss')
参考资料: http://stackoverflow.com/a/1515657

今天学到一个成语-「马齿徒增」

马齿徒增 [mǎ chǐ tú zēng]

【解释】:马的牙齿有多少,就可以知道它的年龄有多大。比喻自己年岁白白地增加了,学业或事业却没有什么成就。徒:白白地。1


很应景的一个词,不过“這句成語通常是用在自我謙虛地表達自己一事無成”2——不知道如实表达自己一事无成能不能用 :D

另附用法示例 XDDD :

马齿徒增用法示例

按固定长度将列表(List)元素分组的一个问题(Python内置函数zip()的用法)

昨天在群里有人问了这样一个问题:

请问 a = [1,2,3,4,5,6,7,8,9] 怎么变成 [(1,2,3),(4,5,6,),(7,8,9)]?
我第一反应是用列表推导,在群里说了自己的想法:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [(a[i], a[i+1], a[i+2]) for i in range(len(a))[::3]]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
群里有人马上给出了更pythonic的方法:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> zip(a[::3], a[1::3], a[2::3])
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
然后又有人指出我给出的写法会有IndexError的问题,并给出了改进过的列表推导式的解决方案:
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [a[x: x+3] for x in range(0, len(a), 3)]
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 当然也可以用tuple()把List转换成Tuple,不过意义不大
# 另外range有第三个参数,比用[::3]的形式看起来优雅一些
# 还有就是列表元素较多的时候用xrange()会比range()更好一些
>>> [tuple(a[x: x+3]) for x in range(0, len(a), 3)]
[(1, 2, 3), (4, 5, 6), (7, 8, 9)]
最值得记一下的是Python内置函数zip(),平时很少用到这个函数,其实还是很实用的。

zip()的用法如下:

zip([iterable, ...])
官方文档里面对zip()的说明如下:
This function returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterables. The returned list is truncated in length to the length of the shortest argument sequence. When there are multiple arguments which are all of the same length, zip() is similar to map() with an initial argument of None. With a single sequence argument, it returns a list of 1-tuples. With no arguments, it returns an empty list.

The left-to-right evaluation order of the iterables is guaranteed. This makes possible an idiom for clustering a data series into n-length groups using zip([iter(s)]n).


感觉有几点比较值得注意:

  • 返回值是一个列表(list), 列表内的元素是元组(tuple)
  • 返回的列表长度和作为参数的序列中最短的序列一样
  • 返回结果的组合顺序是从左至右

其实是很简单的问题,一说就知道(,不说想不到 :D)。

另: 内置函数map(): https://docs.python.org/2/library/functions.html#map

OSX中查看和显示实时网速

系统版本:OSX Yosemite 10.10.2

很多程序(特别是命令行程序)在进行在线更新、下载等活动的时候不显示进度条或者速度,如果下载的内容很大时很难确定是否正常在更新或下载。

Windows下很容易找到带实时网速监控的软件(比如说国内很多电脑管家类软件的加速球等)。MAC上也有这样的软件,比如口碑很好的iStat Menus等,不过类似的软件要么很久不更新要么就是收费——而且往往还不便宜。

如果像我一样只需要最基本的系统状态监控功能,查看一下实时的CPU或是网络的使用情况等,那系统自带的活动监视器就完全能满足这样的需求。

可以按下 command ⌘ + 空格 输入 活动监视器 来打开这个程序,打开后就可以看到系统的使用情况。如果不想一直开着这个窗口,可以点击 显示 - DOCK图标 选择要显示项目后就能在DOCK栏上实时监控情况了。程序默认的更新频率有点慢,可以在 显示 - 更新频率 调高。

最后效果如图,有点简陋,不过够了。

show-network-status-on-dock