7-12.Python 中单下划线和双下划线 & 字符串格式化:%和.format | 迭代器和生成器

7 Python 中单下划线和双下划线 

>>> class MyClass():

...     def __init__(self):

...             self.__superprivate = "Hello"

...             self._semiprivate = ", world!"

>>> mc = MyClass()

>>> print mc.__superprivate

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

AttributeError: myClass instance has no attribute '__superpriva te'

>>> print mc._semiprivate , world!

>>> print mc.__dict__

{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}

__foo__:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突.

_foo:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式. __foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名.

 

8 字符串格式化:%.format 

.format在许多方面看起来更便利.对于%最烦人的是它无法同时传递一个变量和元组.你可能会想下面的代码不会有什么问题:

"hi there %s" % name

但是,如果name恰好是(1,2,3),它将会抛出一个TypeError异常.为了保证它总是正确的,你必须这样做:

"hi there %s" % (name,)   # 提供一个单元素的数组而不是一个参数

但是有点丑..format就没有这些问题.你给的第二个问题也是这样,.format好看多了. 你为什么不用它? 不知道它(在读这个之前) 为了和Python2.5兼容(譬如logging库建议使用%(issue #4))

 

9 迭代器和生成器 

迭代器

对序列(列表、元组)、字典和文件都可以用iter()方法生成迭代对象,然后用next()方法访问。 python3.x,迭代器对象实现的是__next__()方法,不是next()。

python3.x中有一个内建函数next(),可以实现next(it),访问迭代器,这相当于于python2.x中的it.next()(it是迭代对象)。

通过range()得到的列表,会一次性被读入内存,而xrange()返回的对象,则是需要一个数值才从返回一个数值。

迭代器的确有迷人之处,但是它也不是万能之物。比如迭代器不能回退,只能如过河的卒子,不断向前。另外,迭代器也不适合在多线程环境中对可变集合使用如果是迭代器,就可以用for循环来依次读出其值。生成器

生成器必须是可迭代的,可以理解为非常方便的自定义迭代器

 

10 *args and **kwargs 

*args和**kwargs只是为了方便并没有强制使用它们.

当你不确定你的函数里将要传递多少参数时你可以用*args.例如,它可以传递任意数量的参数:

>>> def print_everything(*args):         for count, thing in enumerate(args):

...         print '{0}. {1}'.format(count, thing)

>>> print_everything('apple', 'banana', 'cabbage')

0. apple

1. banana 2. cabbage

相似的,**kwargs允许你使用没有事先定义的参数名:

>>> def table_things(**kwargs):

...     for name, value in kwargs.items():

...         print '{0} = {1}'.format(name, value) >>> table_things(apple = 'fruit', cabbage = 'vegetable') cabbage = vegetable

apple = fruit

你也可以混着用.命名参数首先获得参数值然后所有的其他参数都传递给*args 和**kwargs.命名参数在列表的最前端.例如:

def table_things(titlestring, **kwargs)

*args和**kwargs可以同时在函数的定义中,但是*args必须在**kwargs前面. 当调用函数时你也可以用*和**语法.例如:

>>> def print_three_things(a, b, c):

...     print 'a = {0}, b = {1}, c = {2}'.format(a,b,c) ...

>>> mylist = ['aardvark', 'baboon', 'cat']

>>> print_three_things(*mylist)

a = aardvark, b = baboon, c = cat

就像你看到的一样,它可以传递列表(或者元组)的每一项并把它们解包.注意必

须与它们在函数里的参数相吻合.当然,你也可以在函数定义或者函数调用时用*.

 

11、 面向切面编程 AOP 和装饰器 

这个AOP一听起来有点懵,同学面阿里的时候就被问懵了… 装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。

概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

12、 鸭子类型 

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

我们并不关心对象是什么类型,到底是不是鸭子,只关心行为。

比如在python中,有很多file-like的东西,比如StringIO,GzipFile,socket。

它们有很多相同的方法,我们把它们当作文件使用。

又比如list.extend()方法中,我们并不关心它的参数是不是list,只要它是可

迭代的,所以它的参数可以是list/tuple/dict/字符串/生成器等.

鸭子类型在动态语言中经常使用,非常灵活,使得python不想java那样专门去弄一大堆的设计模式。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值