3 Replies - 329 Views - Last Post: 21 October 2019 - 01:38 PM Rate Topic: -----

#1 krishnaar   User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 17
  • Joined: 25-December 15

Difference between methods

Posted 21 October 2019 - 08:11 AM

Hello Experts,

A python newbie there. I am trying to understand the difference between __method__ and other methods that I get here:

 >>> import sys
>>> dir(sys)
['__displayhook__', '__doc__', '__egginsert', '__excepthook__', '__name__', '__package__', '__plen', '__stderr__', '__stdin__', '__stdout__', '_clear_type_cache', '_current_frames', '_getframe', '_mercurial', 'api_version', 'argv', 'builtin_module_names', 'byteorder', 'call_tracing', 'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_clear', 'exc_info', 'exc_type', 'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info', 'float_repr_style', 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags', 'getfilesystemencoding', 'getprofile', 'getrecursionlimit', 'getrefcount', 'getsizeof', 'gettrace', 'hexversion', 'last_type', 'last_value', 'long_info', 'maxint', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'py3kwarning', 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit', 'settrace', 'stderr', 'stdin', 'stdout', 'subversion', 'version', 'version_info', 'warnoptions']

>>> a={'name':'test'}
>>> dir(a)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']

Is there any use case for __method__ vs other methods?

Is This A Good Question/Topic? 1
  • +

Replies To: Difference between methods

#2 atraub   User is offline

  • Pythoneer
  • member icon

Reputation: 835
  • View blog
  • Posts: 2,267
  • Joined: 23-December 08

Re: Difference between methods

Posted 21 October 2019 - 08:57 AM

A method that has __methodName__ is generally a method that is not intended to be accessed directly, these are often called magic methods. for example:

Do: a["name"]

So, __getitem__ is actually a magic method that allows you to program what happens when you use the bracket notation on your object. For more information on other magic methods, check out this handy guide.

One more, just for giggles.

Do: len(a)

This post has been edited by atraub: 21 October 2019 - 08:59 AM

Was This Post Helpful? 0
  • +
  • -

#3 DK3250   User is offline

  • Pythonian
  • member icon

Reputation: 562
  • View blog
  • Posts: 1,798
  • Joined: 27-December 13

Re: Difference between methods

Posted 21 October 2019 - 12:44 PM

When I started learning python, those 'magic' methods were a bit scaring - something like __repr(self)__ had an aura of mysticism that kept me away.

Eventually I got to the class object where __init__(self, ...) is unavoidable. In the beginning is was just something I wrote without really understanding it - but I got used to the leading and trailing underscores.

At some point in time I wanted to make calculations using vectors. Now things got messy, I wrote something like this:
class Vector():
    def __init__(self, pos):
        self.x = pos[0]
        self.y = pos[1]

    def add(self, other):
        new_x = self.x + other.x
        new_y = self.y + other.y
        return Vector((new_x, new_y))

# It worked like this:

a = Vector((1, 2))
b = Vector((3, 4))

c = a.add(b )  # Uhh, this is ugly

So, I wanted to get rid of this ugly addition (and similar for other operations) - I was looking for
c = a + b

After some research I realized that the plus is brought in play by a 'magic' method, __add__.

My improved Vector class became:
class Vector():
    def __init__(self, pos):
        self.x = pos[0]
        self.y = pos[1]

    def __repr__(self):
        return "Vector({0}, {1})".format(str(self.x)[:6], str(self.y)[:6])

    def __add__(self, other):
        return Vector([self.x + other.x, self.y + other.y])

# Now I can do
c = a + b  # ..just what I wanted  :-)

The real code is longer, including all relevant vector arithmetic - but that's not the scope for this post.

What I want to point out is the great use you can have playing with those methods (but be careful).
Another point is the use of __repr__(self) - it is great when debugging; look at this:
a = Vector((1, 2))

print(a)  # without __repr__(self)
# output:
<__main__.Vector object at 0x000001FFB9146828>  # not very informative

print(a)  # with __repr__(self)
# output:
Vector(1, 2)  # this is understandable!

Now, I always include a __repr__ method in all my classes.
The difference between __str__ and __repr__ is subtle, I'll leave it to you.

Bottom line: You definitely don't need to start understanding all those 'magic' methods; as your python skills develop, however, they can sometime make (programming) life easier for you...
Was This Post Helpful? 1
  • +
  • -

#4 jon.kiparsky   User is offline

  • Beginner
  • member icon

Reputation: 11736
  • View blog
  • Posts: 19,929
  • Joined: 19-March 11

Re: Difference between methods

Posted 21 October 2019 - 01:38 PM

Just a terminology note: much of the python community avoids the "magic methods" phrasing because "magic" is in general a bad word in programming. The term I hear most often is "dunder methods", short for "double underscore methods".

Definitely worth playing with these, for a couple of reasons. (1) they can make your code cleaner, as suggested above. (2) understanding them can help you understand how core python classes like dicts and lists and sets and stuff work. (3) Thinking about the way these work is useful in terms of thinking about python syntax, and in particularly the rewriting that goes on eg when you write something like my_foo.some_func(bar)[\il] to call a function defined as def some_func(self, first_arg) in the class Foo and what actually happens is [il]Foo.some_func(my_foo, bar). This actually is a little bit magic, in that it's a bit surprising and the relationship between the argument structure in the declaration and the call is not altogether clear at first.

So yeah, don't name functions with leading and trailing dunders unless they're actually intended to do this sort of under-the-hood behavior, but definitely play with the capabilities that this offers you.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1