当前位置: 首页 > 工具软件 > No Spam > 使用案例 >

python list对象无法连续调用extend或append方法,报错‘NoneType‘ object has no attribute ‘extend‘

程鸿畅
2023-12-01
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)

(下面的在玩,熟悉python请直接移步文尾)

为了研究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不返回一个对象呢?
难道是性能?难道是内存?
不不不,

我觉得归根到底还是str是不可变类型,list是可变类型。

a.append("22").append("22") #一样报错

世界那么乱,return给谁看? ------本弱鸡宣言

 类似资料: