在Python中向instancemethods添加属性

2024-05-29 04:24:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我在试图让类装饰器和方法装饰器很好地一起工作时碰到了这种行为。本质上,方法修饰符会用一些伪值将一些方法标记为特殊的,类修饰符会在后面出现并在后面填充值。这是一个简单的例子

>>> class cow:
>>>     def moo(self):
>>>         print 'mooo'
>>>     moo.thing = 10
>>>
>>> cow.moo.thing
10
>>> cow().moo.thing
10
>>> cow.moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow().moo.thing = 5
AttributeError: 'instancemethod' object has no attribute 'thing'
>>> cow.moo.__func__.thing = 5
>>> cow.moo.thing 
5

有人知道为什么cow.moo.thing = 5不工作,即使cow.moo.thing很清楚地给了我10?为什么cow.moo.__func__.thing = 5有效?我不知道它为什么会这样做,但是随机地摆弄列表中的东西,试图让它突然做了一些事情,我不知道为什么。


Tags: 方法noobjectattribute装饰修饰符attributeerrorhas
2条回答

如果要从C修改函数和实例方法的函数属性,则必须检查可调用的类型。

因此,假设您有某种类型的可调用PyObject,您可以这样检查它:

PyObject *callable;  // set to something callable
PyObject *setting;  // set to something
if(PyMethod_Check(callable)){
    PyObject_SetAttrString(PyMethod_Function(callable),"attribute",setting);
}else{
    PyObject_SetAttrString(callable,"attribute",setting);
}
...
// and the inverse
if(PyMethod_Check(callable){         
     if(PyObject_HasAttrString(PyMethod_Function(callable),"attribute")){
        PyObject_DelAttrString(PyMethod_Function(callable),"attribute");
     }
  }else{
     if(PyObject_HasAttrString(callable,"attribute")){
        PyObject_DelAttrString(callable,"attribute");
     }
  }  

现在,agf指出了Python中的实例方法。如果我只是尝试设置实例方法的属性,那么无论我如何从Python访问它,它都找不到该属性。

我遇到了这个问题,李浩毅的问题和agf的回答帮助我理解了需要改变的地方。我想有人会在寻找如何通过C来解决这个问题时,找到这个问题并再次给出答案

编辑: 注意:这是针对Python2.7.x的。Python3.x使用不同的函数调用。

对于属性查找,Python将自动使用附加到实例方法的实际函数。

对于属性设置,则不是。

它们是两个独立的操作,具体取决于您在语句的哪一侧,即使它们都使用.运算符。

当您访问实例方法的__func__时,您将手动访问实际具有moo属性的实际函数。

在Python 3中,由于方法基本上只是函数,所以这将按您的期望工作。

相关问题 更多 >

    热门问题