设置实例方法systax

2024-04-19 18:04:01 发布

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

下面的代码当然毫无意义;它不应该 做任何事,但说明我困惑的是:

class func():
  def __call__(self, x):
   raise Exception("func.__call__ error")

def double(x):
  return 2*x

doubler = func()
doubler.__call__ = double

print doubler(2)

有人能解释一下为什么这样做吗?如果我 想把doubler.__call__设成函数 这需要两个变量;我希望上面的代码会引发一些问题 参数过多错误。什么会传递给什么,什么时候?你知道吗

(然后:如何将doubler.__call__设置为 实际上可以同时访问“self”和“x”?)你知道吗

(上下文:An admittedly silly of-academic-interest example of why I might want to set an instance method this way:每个computable实例都需要自己的Approx方法;为每个实例创建一个单独的子类似乎是“错误的”…)

编辑。可能是一个更好的例子,说明它什么都没有 与魔法方法有关:

class func():
  def call(self, x):
    raise Exception("func.call error")

def double(x):
  return 2*x
doubler = func()
doubler.call = double

print doubler.call(2)

三思而后行,也许以下是正确的方法。 (i) 使用Python对象模型而不是 修补它(二)甚至24小时前与我当时的多原油 我知道我本来希望它能起作用;不知怎么的 对我来说,传递函数似乎很有意义 构造函数应该只取一个变量(iii) 不管我是否从object继承,我认为这意味着它也可以在3.0中工作。你知道吗

class func3(object):
  def __init__(self, f):
    self.f = f
  def __call__(self, x):
    return self.f(x)

def double(x):
  return 2.0*x

f3=func3(double)
print f3(2)

Tags: 方法代码selfreturndef错误exceptionerror
2条回答

这是介于对问题的回答和问题的延续之间的东西。我被亲切地提到another thread,那里或多或少地回答了同样的问题。我没有很好地理解那条线索中的答案,因为我不知道那里的人在谈论什么,因此有一个问题:我下面说的是正确的吗?(如果是,那么这是对上述问题的回答;如果不是,我希望有人解释为什么不…)

(i)由于我将函数赋给func的实例而不是类,因此它现在是“实例方法”,而不是“类方法”。你知道吗

(ii)这就是为什么它没有作为第一个参数传递给实例;这种情况发生在类方法中,而不是实例方法中。。。你知道吗

赋值给doubler.__call__时,就是将函数绑定到实例属性。这将隐藏与class语句中创建的同名的class属性。你知道吗

Python的方法绑定只有在通过实例查找类属性时才起作用。如果属性的值是一个描述符(哪些函数是),那么描述符的__get__方法会被适当的参数调用。对于函数对象,它将方法绑定到实例(因此self自动作为第一个参数传入)。你知道吗

您的第一个示例实际上无法在Python3中工作,只能在Python2中工作。这是因为在Python2中,您正在创建一个“旧式”类,它对实例执行所有方法查找。在新样式的类中(在Python 2中可以通过从object继承获得,或者在Python 3中默认获得)__special__方法,当解释器调用它们时(例如,当您执行doubler(2)来运行doubler.__call__)只在类中查找,而不是在实例的属性中查找。因此,您的第一个示例不会使用新样式的类,但是使用普通方法(call而不是__call__)的版本就可以了。你知道吗

相关问题 更多 >