在python中使用setattr()

时间:2012-03-05 03:11:41

标签: python setattr

我正在寻找有人解释如何使用的基础知识,而不是使用setattr()

我的问题出现了尝试使用一个类方法/函数返回数据然后放入另一个方法/函数。在这种情况下,也许更简单的方法会更好,但我试图理解类的工作原理。这个问题似乎取决于setattr(),这是我尝试相当简单地使用它。

虽然问题并不完全相同,但我正在关注Python The Hard Way, ex42 - while循环@第18-41行。

我尝试编写\__init__(),然后使用getattr(),想一想在课堂上可能需要的东西'命名空间,但这似乎没什么帮助。

#! /bin/python2.6

class HolyGrail(object):

    def __init__(self):
        self.start = 'start_at_init'

    # function definition in question:
    # TypeError: 'str' object is not callable

    def run_it(self):
        start = setattr(self, 'name', 'get_thing')
        start = self.name

        # Something wrong here?
        value_returned = start() #I believe this == self.get_thing()
        use_it(value_returned)

    """
    # alternate function definitions
    # NameError: global name 'start' is not defined

    def __init__(self):
        self.start = 'get_thing'

    def run_it(self):
        go_do_it = getattr(self, start)
        first_output = go_do_it()
        use_it(first_output)
    """

    def get_thing(self):
        return "The Knights Who Say ... Ni!"

    def use_it(self, x):
        print x
        print "We want a shrubbery!"

my_instance = HolyGrail()
my_instance.run_it()

@ Karl Knechtel,@ Amber,@ Chris Morgan感谢您的帮助。

我想我现在可以解释我自己的答案了!这需要更好地把握自我作为我的对象。它是一个实例名称,用属性等东西标记。

班级可以是一个城镇,然后。 getattr找一个房子使用它的名字,这样你就可以尽快打电话给它了,如果你找不到房子就会找到一个不同的地方 - getattr一个'名称'存在,你去寻找它。从一个功能到另一个功能的步骤 作为奖励,你可能有一个默认值,对于获得一个后备默认方法很有用 - 连接失败或什么?

setattr建造一个房子并给它一个名字,以便你以后可以打电话给它。 如果您无法找到它,您可能会重建这个房子,或者去某个特定的地方。 - setattr生成一个属性名称并提供或更改其值,以便稍后调用 也许用户关闭声音,然后未来的方法不输出任何音频。

我本可以通过多种方式编写我的函数,但不需要更改任何属性:

def run_it(self):
    yo = getattr(self, 'get_thing')
    answer = yo()
    setattr(self, 'deal_accepted', self.use_it) #really ott
    no = getattr(self, 'deal_accepted')
    no(answer)

正确更正的代码:

def run_it(self):
    value_returned = self.get_thing()
    self.use_it(value_returned)

5 个答案:

答案 0 :(得分:72)

Python docs说出所有需要说的内容,据我所见。

  

setattr对象名称

     

这是getattr()的对应物。参数是一个对象,一个字符串和一个任意值。该字符串可以命名现有属性或新属性。如果对象允许,该函数会将值分配给属性。例如,setattr(x, 'foobar', 123)相当于x.foobar = 123

如果这还不够,请解释一下你不理解的内容。

答案 1 :(得分:63)

您要将self.name设置为字符串 "get_thing",而不是函数get_thing

如果您希望self.name成为函数,则应将其设置为1:

setattr(self, 'name', self.get_thing)

但是,这对您的其他代码完全没必要,因为您可以直接调用它:

value_returned = self.get_thing()

答案 2 :(得分:10)

<强> SETATTR: 我们使用 setattr 将属性添加到我们的类实例中。我们传递类实例,属性名称和值。并且使用 getattr 我们会检索这些值

例如

Employee = type("Employee", (object,), dict())

employee = Employee()

# Set salary to 1000
setattr(employee,"salary", 1000 )

# Get the Salary
value = getattr(employee, "salary")

print(value)

答案 3 :(得分:4)

假设您要为以前未在代码中编写的实例提供属性。 setattr()正是这样做的。 它需要类self的实例以及要设置的键和值。

class Example:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)

答案 4 :(得分:0)

要添加到其他答案中,我发现setattr()的一个常见用例是使用配置时。通常将文件(.ini文件或其他文件)中的配置解析为字典。因此,您最终得到的像是:

configs = {'memory': 2.5, 'colour': 'red', 'charge': 0, ... }

如果您想将这些配置分配给要存储和传递的类,则可以进行简单分配:

MyClass.memory = configs['memory']
MyClass.colour = configs['colour']
MyClass.charge = configs['charge']
...

但是,遍历配置更加容易,也省去了很多麻烦,setattr()就像这样:

for name, val in configs.items():
    setattr(MyClass, name, val)

只要您的字典键具有正确的名称,它就可以很好地工作并且整洁。

*请注意,字典键必须是字符串,因为它们将是类对象名称。