jes516
jes516

Reputation: 552

In python does self require any object of its same type?

I am reading 9.3.2. Class Objects from the python docs and I was hoping someone can clear up the following:

How come both scenarios return 'hello world'? The first instance I kind of understand (at least I believe I do) because self is referencing the object itself 'MyClass' and I guess passing 'm' to self in the second instance is doing the same? Does the function 'self' just need ANY reference to a 'MyClass' object?

>>> class MyClass:
...     """A simple example class"""
...     i = 12345
...     def f(self):
...         return 'hello world'
...
>>> MyClass.f(MyClass)
'hello world'
>>> m = MyClass()
>>> MyClass.f(m)
'hello world'

Upvotes: 1

Views: 69

Answers (2)

Alexander
Alexander

Reputation: 109756

MyClass.f('what the...')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-cca57c03fecc> in <module>()
----> 1 MyClass.f('what the...')

TypeError: unbound method f() must be called with MyClass instance as first argument (got str instance instead)

mc = MyClass()

mc.f('what?')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-bcd3830312d3> in <module>()
----> 1 mc.f('what?')

TypeError: f() takes exactly 1 argument (2 given)

In the first instance, the function requires an instance of MyClass as the first argument. In the second, the instance is implicitly passed. The string argument What? is thus a second argument to the function which is unexpected.

What you may want:

class MyClass:
    @staticmethod
    def f():
        print('hello world')

>>> MyClass.f()
hello world

mc = MyClass()
>>> mc.f()
hello world

Upvotes: 0

chepner
chepner

Reputation: 532538

Python is "duck-typed", meaning it doesn't matter what type self is, as long as it provides the correct interface. Here, self isn't used in the body of the function, so you could pass absolutely anything to MyClass.f and it would work.

>>> MyClass.f(None)
'hello world'
>>> MyClass.f(9)
'hello world'
>>> MyClass.f("foo")
'hello world'

Upvotes: 3

Related Questions