你能在python中为方法设置一个属性吗?

时间:2013-11-30 21:14:27

标签: python python-3.x

我想知道是否可以使用setattr将属性设置为类中的方法,因为当我尝试时会得到一个错误,该错误将在代码之后显示:

class Test:
    def getString(self, var):
        setattr(self.getString, "string", var)
        return self.getString
test = Test()
test.getString("myString").string

哪些错误AttributeError: 'method' object has no attribute 'string'所以我尝试了它而没有放.string而只是尝试了test.getString("myString")同样的错误,但后来我尝试了它而没有像这样使用类

def getString(var):
    setattr(getString, "string", var)
    return getString

getString("myString").string

它像我想要的那样返回“myString”,所以我如何在一个类中执行此操作,为什么它在一个之外但在一个内部工作?

3 个答案:

答案 0 :(得分:5)

type( test.getString )builtins.method,来自文件(methods),

  

因为方法属性实际存储在底层函数中   object(meth.__func__),绑定方法的设置方法属性是   不允许。尝试在方法上设置属性会导致   AttributeError被提升。

根据您要查找的行为,有(至少)两种可能的解决方案。一种是在类方法上设置属性:

class Test:
    def getString(self, var):
        setattr(Test.getString, "string", var)
        return self.getString

test = Test()
test.getString("myString").string  # > "myString"

test2 = Test()
test2.getString.string # > this is also "myString"

另一种是使用函数对象:

class Test:
    class getStringClass:
        def __call__ ( self, var ):
            setattr( self, "string", var )
            return self

    def __init__( self ):
        self.getString = Test.getStringClass( )

test = Test( )
test.getString( "myString" ).string   # > "myString"

test2 = Test()
test2.getString.string  # > this is error, because it does not
                        # have the attribute 'string' yet

答案 1 :(得分:3)

函数与大多数其他对象一样,您可以自由地向它们添加属性。另一方面,方法......从概念上讲,它们只是函数,但它们的行为略有不同(隐含传递self),因此在函数周围添加了一些额外的粘合剂。

每次评估self.getString时,都会创建一个新的(绑定的)方法对象,它是底层函数的一个瘦包装器(可以作为Test.getString访问)。这些方法对象不允许添加属性,即使它们这样做,您的代码也无法工作,因为它会处理多个不同的方法对象(尽管它们都包含相同的函数)。

您无法使用绑定方法进行此操作。由于您可能希望将字符串附加到Test对象(通过附加到其方法而间接附加),因此可以将其设置为Test的属性。您甚至可以创建自己的对象,其行为类似于方法,但允许属性(您必须在__init__中明确添加它),但老实说,可能有更好的方法可以将数据和方法分开。另一方面,如果要将此属性附加到基础函数(这意味着它由所有Test实例共享),则只需在Test.getString上设置属性。

答案 2 :(得分:0)

所以,我找到了一种方法,但并不是我想要亲自去做。如果有人确实找到了另一种方法来执行以下代码,请随时评论如何执行此操作。

class Test:
    def getString(self, string):
        setattr(self,"newString",self)
        self.newString.string = string
    return self.newString

就像我说的那样,我不觉得我通过这样做完成任何事情,但它适用于我需要的东西,如果你在下面找到另一种评论方式。