Discuss / Python / 请教一下各位 test = Test() setattr(test,'b',2) 和 setattr(Test(),'b',2) 有什么区别

请教一下各位 test = Test() setattr(test,'b',2) 和 setattr(Test(),'b',2) 有什么区别

Topic source

class Test(object): def init(self): self.a = 1 def add_self(self): return self.a + self.a test = Test() setattr(test,'b',2) print(hasattr(test,'b'))

结果为True

class Test(object): def init(self): self.a = 1 def add_self(self): return self.a + self.a setattr(Test(),'b',2) print(hasattr(Test(),'b'))

结果为False

为什么会出现这种结果呢?

因为你两次调用了Test()这样生成了两个Test object,所以第二个object并不含有b attribute.

守候986

#3 Created at ... [Delete] [Delete and Lock User]

print(test)

<__main__.Test object at 0x0000000001E50BE0> print(Test())

<__main__.Test object at 0x0000000001E50940> 可以发现print(test)和print(Test())内存地址不一样。 也就是说test != Test() 你对实例对象test创建了属性'b'不代表Test()也拥有属性'b',因为每次实例化的结果和地址都是不同的。 个人观点勿喷

第二个程序里setattr(Test(),'b',2) print(hasattr(Test(),'b'))改为setattr(Test(),'b',2) print(hasattr(Test(),'b'))就对了。

第二个程序里setattr(Test(),'b',2) print(hasattr(Test(),'b'))改为setattr(Test,'b',2) print(hasattr(Test,'b'))就对了。

刚刚那个输错了……

看了其他人的讨论,发现我回答的有点问题。按照我的改法,Test并非Test类,而是type类。楼主的问题是setattr(Test(),'b',2)和hasattr(Test(),'b')这两个代码中的Test()并非同一个实例。Test()==Test()的结果是False。

setattr(Test(), 'b', 2)print(hasattr(Test(), 'b'))

这里两次调用的Test() 创建的不是同一个实例,第一句调用Test()创建了一个实例,并赋予了b属性。第二句判断属性时,判断的是另一个新生成的实例。

test = Test()setattr(test, 'b', 2)print(hasattr(test, 'b'))

这里是用Test() 创建了一个test实例,所以test有b属性。

霁天13

#8 Created at ... [Delete] [Delete and Lock User]

因为你第一个是给实例设置属性。第二个你是想给这个类的构造函数设置属性,Test()是函数,而且是Test类的构造函数。可以说这是个很荒谬的错误,为什么能有那么多人讨论得那么激烈,都是完全没有编程基础吗?C没学过吗。。。

一盒噪噪

#9 Created at ... [Delete] [Delete and Lock User]

一、首先回应楼上的问题:构造函数

python中的构造函数是 __init__

构造函数的特性:实例化类时,python自动运行,相当于为类对象自动添加属性,把你传入的参数变成类对象self中的参数

所以__init__函数中需要几个参数,你在实例化类的时候就必须传入几个参数(除了自动传入的类对象self)

它不是功能性函数,不需要外界调用,

所以根本不需要有返回值,要记住这一点,不要给 __init__函数写return语句

(说句和问题无关的话:层主的类中根本没有构造函数__init__,而是有一个普通函数init,python在实例化类的时候,根本不会运行init,除非你自己调用init,根本不会有self.a,如果你直接调用add_self,程序会报错)

可以用dir查看一下你写有__init__函数的类,和没有写__init__函数的类,属性列表中都含有且只有一个__init__   

但是你如果在类中写了q函数,属性列表中就会多出来一个 q

你在类定义中把函数名命名为__init__,并没有为类添加了函数__init__,而是改写了类原有的__init__函数,让它在创建类对象自动初始化的是你输入的参数而已

二、了解了构造函数之后就可以知道实例化类(创建类对象)test=Text()这一步实际上是什么了

像层主写的第一个代码中,只有一个Text(),创建了类对象test,无论是用setattr给test添加属性,还是后面hassttr中的test,引用的都是同一个类对象

而第二个代码中,有两个Text(),实际上引用了两次Text的构造函数__init__,创建了两个类对象,但由于没有赋值给变量,所以没有名字指向它,你没有办法引用,过一会python的垃圾回收机制会把它释放掉,就不存在了

你给第一个类对象添加了b这个属性,但是hasattr确是作用在第二个类对象上的,所以结果是False

ps:

大家不了解Test()具体的功能是什么,很正常,因为还没有了解__init__嘛,后面应该会学到的,不用急,本来就很多新手用python入门,简单易学,可以提高积极性,知识体系不全面很正常,一起加油

不对的地方希望指正

一盒噪噪

#10 Created at ... [Delete] [Delete and Lock User]

改正一下叙述错误:层主写的类中的构造函数__init__是类的基本属性中含有的,并不是他写的init(他并没有改写构造函数,而是创建了一个和构造函数毫无关联的函数init)


  • 1

Reply