diff options
| author | Alexandre Constantino <dreaming.about.electric.sheep@gmail.com> | 2016-06-26 14:22:47 +0100 | 
|---|---|---|
| committer | ven <vendethiel@hotmail.fr> | 2016-06-26 15:22:47 +0200 | 
| commit | e72c849556dd7ae9cd1333229b4c007a7229225f (patch) | |
| tree | c5ca8dba2033143356716ee3d0f6c32f8811395a /python3.html.markdown | |
| parent | ec15a36de7bcc56708d7e6d52fabe0296b8cc466 (diff) | |
Python3/en: multiple inheritance (#2217)
* Add __name__ check to make testing easier
* Update say to call print. Add more usage examples
* Move Modules section before Classes
Makes more sense for when explaining inheritance
* Add multiple inheritance example
* Add examples for multiple inheritance
* Add instance check examples
* Fix multiple inheritance example
* Add note on the __name__ variable
Diffstat (limited to 'python3.html.markdown')
| -rw-r--r-- | python3.html.markdown | 197 | 
1 files changed, 147 insertions, 50 deletions
| diff --git a/python3.html.markdown b/python3.html.markdown index 0f5da8f1..7f3702e6 100644 --- a/python3.html.markdown +++ b/python3.html.markdown @@ -601,10 +601,47 @@ list(filter(lambda x: x > 5, [3, 4, 5, 6, 7]))  # => [6, 7]  [add_10(i) for i in [1, 2, 3]]         # => [11, 12, 13]  [x for x in [3, 4, 5, 6, 7] if x > 5]  # => [6, 7] +  #################################################### -## 5. Classes +## 5. Modules  #################################################### +# You can import modules +import math +print(math.sqrt(16))  # => 4.0 + +# You can get specific functions from a module +from math import ceil, floor +print(ceil(3.7))   # => 4.0 +print(floor(3.7))  # => 3.0 + +# You can import all functions from a module. +# Warning: this is not recommended +from math import * + +# You can shorten module names +import math as m +math.sqrt(16) == m.sqrt(16)  # => True + +# Python modules are just ordinary python files. You +# can write your own, and import them. The name of the +# module is the same as the name of the file. + +# You can find out which functions and attributes +# defines a module. +import math +dir(math) + +# If you have a Python script named math.py in the same +# folder as your current script, the file math.py will +# be loaded instead of the built-in Python module. +# This happens because the local folder has priority +# over Python's built-in libraries. + + +#################################################### +## 6. Classes +####################################################  # We use the "class" operator to get a class  class Human: @@ -627,7 +664,11 @@ class Human:      # An instance method. All methods take "self" as the first argument      def say(self, msg): -        return "{name}: {message}".format(name=self.name, message=msg) +        print ("{name}: {message}".format(name=self.name, message=msg)) + +    # Another instance method +    def sing(self): +        return 'yo... yo... microphone check... one two... one two...'      # A class method is shared among all instances      # They are called with the calling class as the first argument @@ -658,71 +699,127 @@ class Human:          del self._age -# Instantiate a class -i = Human(name="Ian") -print(i.say("hi"))     # prints out "Ian: hi" +# When a Python interpreter reads a source file it executes all its code. +# This __name__ check makes sure this code block is only executed when this +# module is the main program. +if __name__ == '__main__': +    # Instantiate a class +    i = Human(name="Ian") +    i.say("hi")                     # "Ian: hi" +    j = Human("Joel") +    j.say("hello")                  # "Joel: hello" +    # i and j are instances of type Human, or in other words: they are Human objects + +    # Call our class method +    i.say(i.get_species())          # "Ian: H. sapiens" +    # Change the shared attribute +    Human.species = "H. neanderthalensis" +    i.say(i.get_species())          # => "Ian: H. neanderthalensis" +    j.say(j.get_species())          # => "Joel: H. neanderthalensis" + +    # Call the static method +    print(Human.grunt())            # => "*grunt*" +    print(i.grunt())                # => "*grunt*" + +    # Update the property for this instance +    i.age = 42 +    # Get the property +    i.say(i.age)                    # => 42 +    j.say(j.age)                    # => 0 +    # Delete the property +    del i.age +    # i.age                         # => this would raise an AttributeError -j = Human("Joel") -print(j.say("hello"))  # prints out "Joel: hello" -# Call our class method -i.get_species()  # => "H. sapiens" +#################################################### +## 6.1 Multiple Inheritance +#################################################### -# Change the shared attribute -Human.species = "H. neanderthalensis" -i.get_species()  # => "H. neanderthalensis" -j.get_species()  # => "H. neanderthalensis" +# Another class definition +class Bat: -# Call the static method -Human.grunt()    # => "*grunt*" +    species = 'Baty' -# Update the property -i.age = 42 +    def __init__(self, can_fly=True): +        self.fly = can_fly -# Get the property -i.age # => 42 +    # This class also has a say method +    def say(self, msg): +        msg = '... ... ...' +        return msg -# Delete the property -del i.age -i.age  # => raises an AttributeError +    # And its own method as well +    def sonar(self): +        return '))) ... (((' +if __name__ == '__main__': +    b = Bat() +    print(b.say('hello')) +    print(b.fly) -#################################################### -## 6. Modules -#################################################### +# from "filename-without-extension" import "function-or-class" +from human import Human +from bat import Bat -# You can import modules -import math -print(math.sqrt(16))  # => 4.0 +# Batman inherits from both Human and Bat +class Batman(Human, Bat): -# You can get specific functions from a module -from math import ceil, floor -print(ceil(3.7))   # => 4.0 -print(floor(3.7))  # => 3.0 +    # Batman has its own value for the species class attribute +    species = 'Superhero' -# You can import all functions from a module. -# Warning: this is not recommended -from math import * +    def __init__(self, *args, **kwargs): +        # Typically to inherit attributes you have to call super: +        #super(Batman, self).__init__(*args, **kwargs)       +        # However we are dealing with multiple inheritance here, and super() +        # only works with the next base class in the MRO list. +        # So instead we explicitly call __init__ for all ancestors. +        # The use of *args and **kwargs allows for a clean way to pass arguments, +        # with each parent "peeling a layer of the onion". +        Human.__init__(self, 'anonymous', *args, **kwargs) +        Bat.__init__(self, *args, can_fly=False, **kwargs) +        # override the value for the name attribute +        self.name = 'Sad Affleck' -# You can shorten module names -import math as m -math.sqrt(16) == m.sqrt(16)  # => True +    def sing(self): +        return 'nan nan nan nan nan batman!' -# Python modules are just ordinary python files. You -# can write your own, and import them. The name of the -# module is the same as the name of the file. -# You can find out which functions and attributes -# defines a module. -import math -dir(math) +if __name__ == '__main__': +    sup = Batman() + +    # Instance type checks +    if isinstance(sup, Human): +        print('I am human') +    if isinstance(sup, Bat): +        print('I am bat') +    if type(sup) is Batman: +        print('I am Batman') + +    # Get the Method Resolution search Order used by both getattr() and super(). +    # This attribute is dynamic and can be updated +    print(Batman.__mro__)       # => (<class '__main__.Batman'>, <class 'human.Human'>, <class 'bat.Bat'>, <class 'object'>) + +    # Calls parent method but uses its own class attribute +    print(sup.get_species())    # => Superhero + +    # Calls overloaded method +    print(sup.sing())           # => nan nan nan nan nan batman! + +    # Calls method from Human, because inheritance order matters +    sup.say('I agree')          # => Sad Affleck: I agree + +    # Call method that exists only in 2nd ancestor +    print(sup.sonar())          # => ))) ... ((( + +    # Inherited class attribute +    sup.age = 100 +    print(sup.age) + +    # Inherited attribute from 2nd ancestor whose default value was overriden +    print('Can I fly? ' + str(sup.fly)) + -# If you have a Python script named math.py in the same -# folder as your current script, the file math.py will -# be loaded instead of the built-in Python module. -# This happens because the local folder has priority -# over Python's built-in libraries.  ####################################################  ## 7. Advanced | 
