引发自:[wiki:PyCNmail/2005-June/011209.html Py的几处不爽]

讨论习惯势力在Py 中的思路

::-- ZoomQuiet [DateTime(2005-06-10T01:34:11Z)] TableOfContents {{{发件人: flyaflyaa <[email protected]> 回复: [email protected] 收件人: [email protected] 日期: 2005-6-8 下午2:29 主题: [python-chinese] py的几处不爽 }}}

揭题

{{{一、

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 如果a中元素是数,用for就不能改变a中元素,只能用filter,map,reduce作复杂 处理了,如果a中元素是list,就可以。不统一。

二、 a = "abccdd" a[0] = 'c" 出错,想改a中的一个元素就要再生成一个新的string,这多慢

三、 函数默认参数是list的话,每次调用都用同一个list,会发生错误。

[10]

[10, 10]

这个问题影响不大,可为什么不改掉,很容易产生错误 }}}

讨论

== i++ = {{{要是有 i++ 就好了..;)

>>> i=1 >>> i+=2 >>> i 3 >>> i++ SyntaxError: invalid syntax >>> ++i 3 >>> ++i 3 >>> i+ SyntaxError: invalid syntax >>> +i 3 >>> i++i 6 >>> i++++i 6 >>> }}}

回答

{{{发件人: Qiangning Hong <[email protected]> 回复: [email protected] 收件人: [email protected] 日期: 2005-6-9 下午3:37 主题: Re: [python-chinese] py的几处不爽 }}}

lyaflyaa wrote:
> 一、
>>>> a = range(10)
>>>> a
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>>> for i in a:
>            i += 1
>>>> a
> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> 如果a中元素是数,用for就不能改变a中元素,只能用filter,map,reduce作复杂
> 处理了,如果a中元素是list,就可以。不统一。

这是因为你没有理解+=操作符和名字绑定的概念。
当i是数字时:i += 1 --> i = i + 1, 这是对"i"这个名字进行重新绑定。
当i是list时:i += [1] --> i.extend([1]),调用的是i的方法,可以改变i的值。
你如果用i = i + [1]就都不会修改a的值了。


> 二、
> a = "abccdd"
> a[0] = 'c"
> 出错,想改a中的一个元素就要再生成一个新的string,这多慢

string都是immutable的,不然不能作为dict的key。
如果你不能一次创建string,请先使用list,把要改的东西都改好了,再使用join
生成string。
如果你一定想要mutable string,请仔细阅读:help(UserString.MutableString)

google python mutable string,你会得到更多资料。

> 三、
> 函数默认参数是list的话,每次调用都用同一个list,会发生错误。
>>>> def  foo( a = []):
>    a.append(10)
>    print a
>>>> foo()
> [10]
>>>> foo()
> [10, 10]
>>>>
> 这个问题影响不大,可为什么不改掉,很容易产生错误

默认参数是在定义函数时而不是在调用时创建的。这是feature不是bug。

const行为

{{{发件人: cpunion <[email protected]> 回复: [email protected] 收件人: [email protected] 日期: 2005-6-9 下午4:12 主题: Re: [python-chinese] py的几处不爽 }}}

python把一些基本类型(包括string)都实现为const,模拟出const行为,即自身值
不变,每个操作都会生成一个新对象。

它并没有什么不统一,恰恰相反,它非常统一,遍历时确实返回了元素的引用,整
数值没有改变的原因是,整数的add操作没有改变它自身,而是返回另一个对象,
可以写一个非常简单的模拟:

>>> class Integer:
   def __init__ (self, value):
       self.value = value
   def __add__ (self, value):
       self.value += value
       return self
   def getValue (self):
       return self.value

>>> class ConstInteger:
   def __init__ (self, value):
       self.value = value
   def __add__ (self, value):
       return ConstInteger (self.value + value)
   def getValue (self):
       return self.value

>>> a = [Integer(i) for i in range (10)]
>>> for i in a:
   i += 1

>>> for i in a:
   print i.getValue ()

1
2
3
4
5
6
7
8
9
10
>>> b = [ConstInteger(i) for i in range (10)]
>>> for i in b:
   i += 1

>>> for i in b:
   print i.getValue ()

0
1
2
3
4
5
6
7
8
9

可见并没有不统一的地方,它也能根据需求做出不同的实现,恰好证明这方面是很
好用的。