阅读OSQA笔记 1

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 importstatement, 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 modor 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的用法完全一致, 这样, 我们就可以在其后的代码段中, 修改普通的外部变量了.....

你可能感兴趣的:(阅读OSQA笔记 1)