Python dot notation (methods)

3

How do you create methods of type dot notation, those that are called object.show () instead of show ( objec ) , or do they apply only to strings, if so why exactly?

    
asked by anonymous 15.06.2017 / 01:08

2 answers

4

Point notation in Python is used to retrieve attributes of objects. In particular in Python, there is no distinction at the moment you use the dot between an "attribute" and a "method" - as in Python everything is an object and what distinguishes the methods is that they are "callable" members ( "callable") of an object.

So to create a method, the most common way is to create a class, and define the methods inside the body of the class with the def <nome> (self, [parametro, ...]): notation - just like we do with loose functions. After that, when creating instances of this class, the methods will be available:

class A:
    def b(self):
         print(f"Método b chamado no objeto {self}")

a = A()
a.b()

If you paste iso in the interactive mode (Python 3.6) the output will look something like:

Método b chamado no objeto <__main__.A object at 0x7f19d24b77b8>

(For versions of Python between 3.0 and 3.5, remove the "f-string" and use the ".format" method.)

There are other ways of putting recoverable attributes by point - for example simple assignment - that can be done as much in the class as in some object instance. Continuing the example above:

def bla():
   print("bla chamado")

a.bla = bla

a.bla()

This time the "a" function becomes an attribute of the a instance of the A class object we created. The biggest difference being that this way it does not automatically get a reference to the instance itself (see, the bla function was defined without the self parameter and would give an error if it was coaxed with self and used in that way).

The rules that Python uses to access an instance or class tribute - and when it automatically adds the self attribute or not - are well-defined in the language. - but they require a certain study to be understood in their entirety, why they cover all the corner cases . For day-to-day use they are often intuitive enough. The Data Model might be the best document to understand the language as a whole and these rules.

A simplified summary just to understand the most basic attribute search - after the point there is an attribute name, and the Python runtime fetches the attribute on the object following these steps:

  • The __getattribute__ method of the object is called with the parameters self and the name of the attribute. As a rule, classes defined in "day to day" code do not redefine the __getattribute__ method - then this method is at the base of the Python object hierarchy - and searches the attribute. The next steps actually occur within of this __getattribute__ pattern. The first of the cases below that "match" is returned as the attribute:
  • Python searches the class and superclass of the object if the attribute exists and is an object of type "data-descriptor" (an object that in turn has the method __get__ E one of __set__ or __del__ ) - I will not detail what happens if he finds to keep this response at an intermediate level. All in all, when we use the decorator @property it falls in this case.
  • If you do not find a descriptor, Python looks at the __dict__ attribute of the instance itself if there is a key with that name. S
  • Python searches the object class for an attribute with that name.
  • If it does not find in the class, it looks in the superclasses, following the order that is in the .__mro__ attribute of the class.
  • If not found, Python calls the __getattr__ method (it is unlike the __getattribute__ ) of the class, baking the attribute name.
  • If the call to __getattr__ fails, a AttributeError exception occurs and the attribute is not retrieved.

Furthermore, it is worth adding that for objects whose classes are defined directly in C, using the Python API, and not in pure Python, it is not usually possible to add new attributes or methods dynamically. That is, you can not hang new methods on the str or int classes of Python, as you can in Ruby.

    
15.06.2017 / 11:28
3

Let's start with an example where 4 methods are created, being init , the first two with the show (obj) notation and the last one with the call that you call 'dot notation. p>

View the code displayed in this response by running on repl.it.

class collection1::
    def __init__(self):
        self.lst = [1,2,3,4,5]

    # Tamanho da collection (função len) 
    def __len__(self):    
        return len(self.lst)

    # Fornece a posição de um item na collection
    def __getitem__(self, position):
        return self.lst[position]

    # Apresenta a collection 
    def show(self):
        print (self.lst)   

Now let's instantiate and execute the methods:

c = collection1()
print (len(c))
5

print (c[3])
4

c.show()
[1, 2, 3, 4, 5]

Named and terminated methods with __ (dunderscore)
These are the special methods, called by some of the "magic methods," the main thing you should know about these methods is that you should not call them directly (although this can be done). Instead of using obj.__len__() or obj.__getitem__[3] you must use len(obj) and obj[3] . Note that if obj is a built-in type, such as list, str, etc. The interpreter will call a function (which may be in cpython) through a shortcut. If the class of which obj is an instance, it has been implemented by you, the interpreter will call the instance method that you have implemented, in __getitem__ and / or __len__ .

Why len is not a method?
Luciano Ramalho in his book Python Fluent , says he asked this question to one of the core developers in 2013 and the key to the response was a quote from The Zen of Python 'praticality beats purity' (The practicality surpasses purity). I recommend the book (no, I'm not earning anything. :-)) for more details.

Implementing our own str in our class:
Let's suppose we needed or wanted to implement a "stuck" str in our class, we would just have to implement __str__ , like this:

def __str__(self):
    return 'Classe especial com uma lista simples'

Now we could use the function str as if it were a function built into python, the difference is that the interpreter will call our function:

obj = collection1()
print (obj)
Classe especial com uma lista simples

Conclusion
Except for the implementations of scape methods , most of the methods you develop will be of the type which you call "point notation", in fact, even the special methods have the same implementation (that of those notation) the difference is only in the call and the magic.

DEMO

    
15.06.2017 / 12:48