-4
import random as rd
q1 = rd.randint(1,10)    
print(dir(q1))

Output is:

['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']

1. I want to know how to use (syntax) all these methods/attributes/functions for my given q1. (I don't know what is attribute/function/method? I just typed them for keyword match)

  1. Here I observe two categories of methods: one with double underscore at both ends and other with none. Example, __abs__ and bit_length. What is the basic different between these two subcategories?

  2. I just want to know is there a general terminology that how to use these methods? For instance, do I have to use . for which methods? and how to use them? Please, give some examples. For example, __eq__ is equal function. I want to check if q1 is equal to 5. My code is:

print(q1.eq(5))

Output is:

AttributeError:'int' object has no attribute 'eq'

Looks like I didn't use it properly. Your answer going to help me to know how to use methods/attributes/functions defined under any given class.

Msquare
  • 293
  • 1
  • 3
  • 15
  • 1
    Try `print(q1.__eq__(5))` – davedwards Aug 17 '18 at 05:52
  • 1
    Firstly, `type(q1)` wouldn't return that. That looks like the value of `dir(q1)`. In any event, those are the attribute names, so you access them using *those names*. However, most of the "dunder" methods, i.e. `__x__` are special hooks into things like operators and the like. You usually do not use those directly – juanpa.arrivillaga Aug 17 '18 at 05:53
  • 2
    Possible duplicate of [Where is the Python documentation for the special methods? (\_\_init\_\_, \_\_new\_\_, \_\_len\_\_, ...)](https://stackoverflow.com/questions/1418825/where-is-the-python-documentation-for-the-special-methods-init-new) – davedwards Aug 17 '18 at 05:55
  • 4
    All of your questions are answered [here](https://docs.python.org/3/reference/datamodel.html). Tl;dr: methods are class attributes that contain functions; instance methods can be called using `instance.method(arglist)` notation, which is identical to `klass.method(instance, arglist...)`. Double underscore methods are special, and typically implement non-method syntax such as operators. In particular, `q1.__eq__(5)` is what is invoked in the background when you do `q1 == 5`. – Amadan Aug 17 '18 at 05:56

1 Answers1

0

I'll give a high level answer to your questions but I recommend to take a look at the Python documentation to get a more in-depth answer.

1) There are essentially two types of attributes an object can have. Objects can have instance attributes that are assigned on a per object basis and class attributes that all instances of that object have access to.

class Employee(object):
    has_benefits = True # class attribute

    def __init__(self, name, badge_number):
        self.name = name # instance attribute
        self.badge_number = badge_number # instance attribute


>> e1 = Employee('bob', 123)
>> e1.name
>> 'bob'
>> e1.has_benefits
>> True
>>
>> e2 = Employee('sarah', 456)
>> e2.name
>> 'sarah'
>> e2.has_benefits
>> True

In this example, every Employee instance created has instance attributes name and badge_number which are specific to that instance, but notice how every Employee instance has access to the class attribute has_benefits which is set to True for all Employees.

A function is some code that can be called by it's name, whereas a method is some code that can be called by it's name that is associated with an object. There is also an instance method which accepts the self argument as it's first parameter

def show_something():
    print('Show something')

class MyClass(object):

    # method
    def display_something():
        print('Display something')

    # instance method
    def print_something(self):
        print('Print something')


>> show_something()
>> 'Show something'
>>
>> MyClass.display_something()
>> 'Display something'
>>
>> mc = MyClass()
>> mc.print_something()
>> 'Print something'

Notice how the function show_something is just some code that we could call by name. Also, notice how the method display_something is bound to our class object and the instance method print_something is bound to an instance of our object. mc.print_something() is the same as MyClass.print_something(mc)

2) Running dir() on an object returns a list of all of the object's attributes. Some attributes are considered special attributes that are surrounded by double underscores. Some attributes are callable which we can determine by passing the attribute to the built-in function callable() which will return True if the attribute is callable, False otherwise.

Attributes without the surrounding double underscores are also attributes and methods can be attributes too. __abs__ gets called when you run the abs() built-in function which returns the absolute value of the object passed-in. bit_length is a method that returns the number of bits which represent the passed-in object. And yes, you access these attributes with the . (dot) syntax.

>> my_num = 5
>> my_num.real
>> 5
>> callable(my_num.bit_length)
>> True
>> my_num.bit_length()
>> 3
>> my_num.__class__
>> <class 'int'>

3) Lastly, we can define an object that implements some special methods that get used by Python when we run specific actions such as membership testing and getting the length of a collection. I'll show some basic examples:

class MyCollection(object):
    def __init__(self, data):
        self.my_data = data

    def __contains__(self, item):
        return item in self.my_data

    def __len__(self):
        return len(self.my_data)

    def __iter__(self):
        for item in self.my_data:
            yield item

    def __add__(self, rhs):
        if not isinstance(rhs, MyCollection):
            return NotImplemented
        return self.my_data + rhs.my_data

    def __eq__(self, rhs):
        if not isinstance(rhs, MyCollection):
            return NotImplemented
        return self.my_data == rhs.my_data

    def __ne__(self, rhs):
        if not isinstance(rhs, MyCollection):
            return NotImplemented
        return self.my_data != rhs.my_data

Give it a try:

>> mc1 = MyCollection([1,2,3,4,5])
>> mc2 = MyCollection([6,7,8,9])
>> mc3 = MyCollection([1,2,3,4,5])
>>
>> 3 in mc1 # calls __contains__
>> True
>>
>> len(mc1) # calls __len__
>> 5
>>
>> [item for item in mc1] # calls __iter__
>> [1,2,3,4,5]
>>
>> mc1 + mc2 # calls __add__
>> [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>
>> mc1 == mc2 # calls __eq__
>> False
>>
>> mc1 != mc2 # calls __ne__
>> True
>>
>> mc1 == mc3 # calls __eq__
>> True

I hope this helped!

shahbazkhan
  • 136
  • 1
  • 8
  • Thanks a lot for helping me to understand the Python functions, methods and attributes. In your whole answer, what I liked and expected is this: `explaining attributes with double-underscore at both ends and others'. I wanted to know, is there a general way to tell that we can use a `double_underscore' attribute in this way and a `non-underscore' attribute in this way. This answer helps me to understand each attribute. Moreover, I can enjoy applying these things to different functions. – Msquare Aug 21 '18 at 04:58
  • Attributes with double-underscores at both ends are considered "special" attributes that are used by underlying Python mechanisms like I showed in my answer above. Typically, we override these special attributes if we want to gain more control of our objects. You can access all attributes whether they are "special" attributes or not with the dot syntax and there is no general rule to tell when we should access each attribute. You access each attribute when you need to. It's as simple as that! If you liked the answer, maybe accept it so others may benefit as well? :) – shahbazkhan Aug 22 '18 at 01:55