Discuss / Python / 问题请教

问题请教

Topic source

以obj为例,请问setattr(obj,'y',19)和obj.y=19有什么区别呢?感觉后者写法上貌似更简洁直观,而且廖老师说的是在不知道对象信息的时候,我们才用hasattr()之类的函数,但是如果通过hasattr函数确定了对象含有某个属性之后,为什么不直接用obj.y的形式对该属性进行读取和赋值呢,因为貌似使用getattr(obj,'y')的前提就是已经知道了obj含有属性y,而setattr(obj,'y',19)则感觉不需要知道obj结构,相当于自行新增的一个属性y,感觉完全可以用obj.y=19替代。

廖雪峰

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

给你举个例子:

# 把dict的key - value复制到obj,前提是obj有对应的property
def dict2bean(obj, d):
    for k, v in items(d):
        if hasattr(obj, k):
            setattr(obj, k, v) # 能写成obj.k = v吗?

有些时候那个property name也是变量

改成obj.k=v后,obj多了个叫k的变量2333333

阿不对,多了一个叫k的属性,而且k值与for循环中最后一个的值相同

小菜

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

我感觉差不多

还是廖老师厉害,一段代码点破,翻译一下:

正常使用 setattr(obj,'y',19) 中的‘y’,此时并不是一个变量,它只是一个字符串,起着匹配的作用

而廖老师代码中setattr(obj, k, v)的k虽然也是匹配作用,但此时并非一个简单的字符串,而是一个变量,指向每次循环对应的dic中的key值,若写成obj.k = v这个,obj中就会生成k这个属性,故不行

wang

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

请问下这段代码有什么问题?key name的value并没有改变成。

d={'name':'sam','age':26,'gender':'male'}

class Object(object):

    def __init__(self,k,v):

        self.k=k

        self.v=v

    def dict2bean(self,key,value):

        for k,v in d.items():

            if hasattr(self,key):

                setattr(self,key,value)

myobj=Object('name','Liu')

myobj.dict2bean('name','Liu')

Alian

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

    def __init__(self,k,v):

        self.k=k

        self.v=v

注意这里的self.k与self.v,me = Object('name','liu')后,me有两个属性,分别是me.k和me.v,而不是me.name和me.liu。

所以if hasattr(self,key): 这里的判断就是False,另外for k,v in d.items():这句好像也有问题,因为你传入的参数是key和value。

我的一些小看法,可能有勿,还请谅解。

wang

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

后来研究下,hasattr(self,"xx"): 里面的参数需要加冒号。 而且我这个dict2bean函数并没有去改变字典D内部的value,只是在改变函数dict2bean本身的参数的值。

所以最后D的输出是不会变的。现在改成这样就正确了

d={'name':'sam','age':26,'gender':'male'}

class Object(object):
    def __init__(self,k,v):
        self.k=k
        self.v=v
    def dict2bean(self,k,v):
        for key,value in d.items():
            if hasattr(self,"k"):
                d[k]=v

myobj=Object('name','Liu')
myobj.dict2bean('name','Liu')
print(d)

小糊涂

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

wang

dict2bean函数里if的判断条件,由于你传进去的参数k就是myobj的属性,所以结果永远是true。如果你把d[k]=v改成d[key]=v会发现字典里的所有value都会变成'Liu'

下面是我的思路,欢迎讨论

d={'name':'jam','age':26,'gender':'male'}

class Object(object):

    def __init__(self,note,name):

        self.note=note

        self.name=name

    def dict2bean(self,dict1):

        for k,v in dict1.items():

            if hasattr(self,k):

                print('has the value')

                setattr(self, k, v)          #第一种:给myobj实例中name起一个新名字

                # dict1[k] = self.name         #第二种:修改字典d中name所对应的value值

myobj=Object('name','Liu')

print(myobj.note,myobj.name)

myobj.dict2bean(d)

print(d)

print(myobj.note,myobj.name)


  • 1
  • 2

Reply