From Programming Language Pragmatics, by Scott
Both Python and Ruby are more flexible than PHP or more traditional object- oriented languages regarding the contents (members) of a class. New fields can be added to a Python object simply by assigning to them: my_object.new_field = value. The set of methods, however, is fixed when the class is first defined. In Ruby only methods are visible outside a class (“put” and “get” methods must be used to access fields), and all methods must be explicitly declared. It is possible, however, to modify an existing class declaration, adding or overriding methods. One can even do this on an object-by-object basis. As a result, two objects of the same class may not display the same behavior.
What does "The set of methods, however, is fixed when the class is first defined" mean?
I seem to have found a counterexample:
>>> class E:
... pass
...
>>> E.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'E' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'E' objects>})
>>> def myfun():
... pass
...
>>> E.mf=myfun
>>> E.__dict__
mappingproxy({'__module__': '__main__', '__dict__': <attribute '__dict__' of 'E' objects>, '__doc__': None, '__weakref__': <attribute '__weakref__' of 'E' objects>, 'mf': <function myfun at 0x7f6561daba60>})
Like shown in the question: it's trivial to add a function to a class object that is behaving just like any method would:
def fake_method(self,idx):
print(self, idx)
class MyClass(object):
pass
MyClass.new_method = fake_method
n = MyClass()
n.new_method(10)
# <__main__.MyClass object at 0x000001BBA6E90860> 10
You can also add "method"-like "callable attributes" to an instance:
import types
def fake_method(self,idx):
print(self, idx)
class MyClass(object):
pass
n = MyClass()
n.new_method = types.MethodType(fake_method, n)
n.new_method(10)
# <__main__.MyClass object at 0x000001BBA6E9C2E8> 10
The types.MethodType
is needed here because it would otherwise behave like a staticmethod
.
My summary: Either I'm missing some crucial point of the quote or it's wrong.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With