a=[1,2]
b=[3,4]
c=[5,6]
a.extend(b).extend(c)
运行后报错:
a.extend(b).extend(c)
AttributeError: 'NoneType' object has no attribute 'extend'
我百思不得其解,因为
s="hello world"
print(s.replace("hello","haha").replace("world","word"))
# [out]:haha word
进行
print(x=a.extend([1,2]))
# [out]:
原来是列表a
调用方法extend
后返回了一个None
(方式1)
为了研究OOP的一些特点,我继续做实验:
猜想,obj.meth1().meth2()
的实现过程为(方式2)
(其实是进一步通过__dict__,__getattr__,__getattribute__,__class__
等获取并返回的)
meth1_ret=obj.meth()
meth1_ret.meth2()
class Spam:
def meth1(self):
print("Call meth1")
return self
def meth2(self):
print("Call meth2")
return None
spam=Spam()
spam.meth1().meth2() #success
spam.meth2().meth1() #AttributeError: 'NoneType' object has no attribute 'meth1'
我们再看一下方式2和方式2速度对比:
class Spam:
def meth1(self):
print("Call meth1")
[str(x) for x in range(1, 1000000)]
return self
def meth2(self):
print("Call meth2")
[str(x) for x in range(1, 1000)]
return None
spam=Spam()
import time as t
res=[]
def test_speed():
start=t.time()
spam.meth1().meth2() #方法1
middle=t.time()
m=spam.meth1() #方法2
m.meth2()
end=t.time()
if middle-start>end-middle:res.append(1)
[test_speed() for i in range(1,100)]
print(len(res))
第一次实验方法1胜出57回,第二次胜出44回,目前来看性能无太大差别。。。想着也是,不就创建个变量名嘛。
内存测试:
from memory_profiler import profile
def one(): #方法1
spam.meth1().meth2()
def two(): #方法2
m=spam.meth1()
print(id(m),id(spam.meth1()))
m.meth2()
@profile(precision=10)
def run():
one()
two()
one()
run()
"""
Line # Mem usage Increment Occurences Line Contents
============================================================
22 54.4335937500 MiB 54.4335937500 MiB 1 @profile(precision=10)
23 def run():
24 54.4335937500 MiB 0.0000000000 MiB 1 one()
25 54.4335937500 MiB 0.0000000000 MiB 1 two()
26 54.4335937500 MiB 0.0000000000 MiB 1 one()
"""
经过内存测试发现也无差别,因为对象一直在,都在同指向同一块内存。(其实我怀疑是我不会测试)。
。。。。。速度内存测试好像搞错测试方法了。。。太菜了。。。
那为什么extend不返回一个对象呢?
难道是性能?难道是内存?
不不不,
a.append("22").append("22") #一样报错
世界那么乱,return给谁看? ------本弱鸡宣言