سؤال

See this example for a demonstration:

>>> class M:
       def __init__(self): self.x = 4
>>> sample = M()
>>> def test(self):
        print(self.x)
>>> sample.test = test
>>> sample.test()
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    sample.test()
TypeError: test() missing 1 required positional argument: 'self'

Why?

هل كانت مفيدة؟

المحلول

The test method you are assigning to sample.test is not bound to the sample object. You need to manually bind it like this

import types
sample.test = types.MethodType(test, sample)
sample.test()
# 4

نصائح أخرى

Functions are objects like any other and there needs to be consistency on what happens when objects are assigned to names, regardless of where the names are (i.e. in local namespace or on as attributes on an object).

When you define a function with def you are binding a function to the name after def, and when you do assignment like some_object.f = my_function you are also binding the function to a name. There's no magic in the assignment process that would change the nature of the function.

There is magic in the class definition process. Functions defined as instance methods (that is, functions defined inside a class definition) are not simply assigned as attributes to instances, but instead they are bound to the instance using a descriptor.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top