1.关于hasattr函数
hasattr(object, name)
The arguments are an object and a string. The result is True if the string is the name of one of the object’s attributes, False if not. (This is implemented by callinggetattr(object, name) and seeing whether it raises an exception or not.)
此处object不仅仅是类对象,在python中一切皆为对象,可以是函数等,所以可以用hasattr()对url函数的对象使用,诸如:
u = url(r'^$', app.readers.index, name='index')
hasattr(u,"name")
2.关于__import__函数
In fact, the behaviour of __import__()
is entirely because of the implementation of the import
statement, which calls __import__()
. There's basically five slightly different ways __import__()
can be called by import
(with two main categories):
import pkg
import pkg.mod
from pkg import mod, mod2
from pkg.mod import func, func2
from pkg.mod import submod
In the first and the second case, the import
statement should assign the "left-most" module object to the "left-most" name: pkg
. After import pkg.mod
you can do pkg.mod.func()
because theimport
statement introduced the local name pkg
, which is a module object that has a mod
attribute. So, the __import__()
function has to return the "left-most" module object so it can be assigned topkg
. Those two import statements thus translate into:
pkg = __import__('pkg')
pkg = __import__('pkg.mod')
In the third, fourth and fifth case, the import
statement has to do more work: it has to assign to (potentially) multiple names, which it has to get from the module object. The __import__()
function can only return one object, and there's no real reason to make it retrieve each of those names from the module object (and it would make the implementation a lot more complicated.) So the simple approach would be something like (for the third case):
tmp = __import__('pkg')
mod = tmp.mod mod2
mod2 = tmp.mod2
However, that won't work if pkg
is a package and mod
or mod2
are modules in that package that are not already imported, as they are in the third and fifth case. The __import__()
function needs to know that mod
and mod2
are names that the import
statement will want to have accessible, so that it can see if they are modules and try to import them too. So the call is closer to:
tmp = __import__('pkg', fromlist=['mod', 'mod2'])
mod = tmp.mod mod2
mod2 = tmp.mod2
which causes __import__()
to try and load pkg.mod
and pkg.mod2
as well as pkg
(but if mod
or mod2
don't exist, it's not an error in the __import__()
call; producing an error is left to theimport
statement.) But that still isn't the right thing for the fourth and fifth example, because if the call were so:
tmp = __import__('pkg.mod', fromlist=['submod'])
submod = tmp.submod
then tmp
would end up being pkg
, as before, and not the pkg.mod
module you want to get thesubmod
attribute from. The implementation could have decided to make it so the import
statement does extra work, splitting the package name on .
like the __import__()
function already does and traversing the names, but this would have meant duplicating some of the effort. So, instead, the implementation made __import__()
return the right-most module instead of the left-most one if and only if fromlist is passed and not empty.
(The import pkg as p
and from pkg import mod as m
syntax doesn't change anything about this story except which local names get assigned to -- the __import__()
function sees nothing different when as
is used, it all remains in the import
statement implementation.)
3.python的闭包(3.0之前及之后)
首先, 说说python里面的闭包吧:
1. 需要函数嵌套, 就是一个函数里面再写一个函数.
2. 外部函数需要返回一个内部函数的引用
3. 外部函数中有一些局部变量, 并且, 这些局部变量在内部函数中有使用
概念:
1. 自由变量: 外部函数中定义的局部变量, 并且在内部函数中被使用.
2. 闭包: 那个使用了自由变量并被返回的内部函数就称为闭包.
一个例子:(来自<python核心编程>)
def counter(start_at=0):
count = [start_at]
def incr():
count[0] += 1
return count[0]
return incr
问题的提出: 关于python闭包的一个问题 , 呵呵, 论坛一位网友提出的问题: 自由变量只能是list吗?
def f():
a = [1, 2]
b = 1
c = 'hello'
d = (1, )
e = True
f = {1: 2}
def inf():
print locals()
a[0] += 1
b = 2
c = 3
d = (2, )
e = False
f[1] = 3
return a[0]
return inf
a = f()
t = a()
print t
上面这一段代码中, 内部函数inf第一句打印了locals(), 最终打印的结果只有a和f, 这段代码我的测试环境是python2.5, windows平台...对于这段, 我总结:
1. 内部函数中, 遇到一个变量, 如果是试图改变它的子元素(集合类型)或自己名称空间(比如函数作为变量或对象作为变量时, 自己同时是名称空间)内部其他名称的引用时, 将会合法的引用到外部变量.
2. 内部函数中, 遇到一个变量, 如果试图直接改变其自身, 多数情况都会得到"使用前未指定"的错误, 请看原因:
def f():
a = 1
def inf():
a += 1
return a
return inf
最重要的就在a+=1这一句, 这里, python实际上会认为你是在创建一个新的本地变量并为他赋值, 也就是说, python的解释器认为a+=1是a = a + 1, 而此时就很明显了, 本地变量中目前没有a, 所以, 就得到了我们上面说的那个错误...
3. 通常需要在闭包内部去修改外部函数变量的时候, 我们需要借助一些集合类型或有名称空间的对象进行操作.
以上这部分都是python3.0之前的情况, 在3.0之后, 加入了一个新的关键字nonlocal, 就像当初的global关键字解决函数内修改全局变量的问题一样漂亮, nonlocal将闭包内修改外部变量的问题也很优美的搞定了.
def f():
a1 = 'hello'
a2 = 1
a3 = o()
a3.x = 1
def inf():
print(locals())
nonlocal a2, a1
a1 += ' world'
a2 += 2
a3.x += 1
return a1, a2, a3
return inf
上面的代码中, 通过在闭包内, 使用外部变量之前, 用nonlocal去声明一下要在闭包中进行修改的那两个变量不是本地变量, 就OK了, 和global的用法完全一致, 这样, 我们就可以在其后的代码段中, 修改普通的外部变量了.....