Python Classes And Objects | Python 3 Class Tutorial For Beginners

Python Classes And Objects | Python 3 Class and Objects Tutorial For Beginners 2019. Here in this blog post Coding compiler sharing a tutorial on Python 3 classes and objects for beginners. This Python tutorial is for beginners and intermediate learners who are looking to master in Python programming. Experienced Python programmers also can refer this tutorial to brush-up their Python 3 programming skills. Let’s start learning Python 3.

Python Classes And Objects

Here we will discuss on each and every sub-topic of Python classes and objects.

Python Classes and Objects Tutorial
1. Python Classes 10. Inheritance
2. Scope & Namespace 11. Multiple Inheritance
3. Examples of scopes and namespaces 12. Private Variables
4. Class Definition 13. Supplement
5. Class Objects 14. Exception Classes
6. The Instance Object 15. Iterators
7. Method Objects 16. Generator
8. Class and Instance Variables 17. Generator Expressions
9. Class Instructions 18. Python Classes Objects Conclusion

Related Articles: Python Getting Started Guide  |  Introduction to Python

Python Class

Python’s class mechanism implements classes in the language with minimal new syntax and semantics. It is a mix of class mechanisms in the C++ or Modula-3 language. Like modules, Python’s classes do not establish an absolute barrier between users and definitions, but instead rely on the elegance of the user not to “force the definition”.

On the other hand, most of the important features of the class are fully preserved: class inheritance mechanism allows multiple inheritance, derived classes can override any method or class in the base class, can use the same method name to call the base class method. Objects can contain any number of private data.

In C ++ terms, all of the class members (including the data members) are public ( public ). There is no easy way to refer members of an object in a member method, a method function needs to have the referenced object as the first parameter when it is defined, and invokes the object implicitly when it is called.

Like in Smalltalk, classes are also objects. This provides import and rename semantics. Unlike C++ and Moduls, most built-in operators (algorithm operators, subscripts, etc.) with special syntax can be redefined for the needs of the class.

When discussing classes, there are not enough consensus terms, and I occasionally borrow some from Smalltalk and C++. I prefer to use the Modula-3 term because Python’s object-oriented syntax is more like it than C++, but I think few readers have heard of this.

Related Article: Python Interpreter Tutorial

1. Terminology related

Objects have properties, and multiple names (in multiple scopes) can be bound to the same object. It is called an alias in other languages. This is usually ignored in the first impression of Python, and can be safely ignored when dealing with immutable primitive types (numbers, strings, tuples).

However, when calling mutable objects such as lists and dictionaries, or most program external types (files, forms, etc.) to describe entities, the semantics of the aliases have (intentionally) influence on the semantics of Python code. This usually helps the optimization of the program, because in some ways the aliases behave like pointers.

For example, you can easily pass an object because only a pointer is passed through the inheritance. And if a method changes an object passed as a parameter, the caller can receive the change — this eliminates the need for two different parameter passing mechanisms, like the Pascal language.

2. Python scopes and namespaces

Before introducing classes, I first introduce some rules about Python scope. The definition of the class is very clever use of the namespace, to fully understand the following knowledge, you need to understand the working principle of the scope and namespace. In addition, all this knowledge is very useful to any advanced Python programmer.

Let’s start with some definitions.

Namespaces are mappings from naming to objects. The current namespace is primarily implemented through Python dictionaries, but it is usually not concerned with the specific implementation (unless for performance considerations) and may change its implementation in the future.

Related Articles: Learn Python In One Day

Here are some examples of namespaces: a set of built-in naming ( functions like abs() , and built-in exception names), global naming in modules, and local naming in function calls. In a sense, the set of attributes of an object is also a namespace.

A need to know about namespaces important thing is different namespace name without any contact, for example, two different modules may both define a named maximizefunction without confusion – users must module name prefix To quote them.

. “” By the way, I call any of Python named after attributes – for example, the expression z.realof reala target zof a property. Strictly speaking, references to names in modules are attribute references: in the expression modname.funcnamein modnamea module object, funcnameis one of its attributes.

Therefore, the module’s properties have a direct mapping relationship with the global names in the module: they share the same namespace!

Properties can be read-only or written. In the latter case, you can assign values to the attributes. You can do so: . Writable attributes can also be deleted using the del statement. For example: will the deleted object attributes.modname.the_answer = 42del modname.the_answermodnamethe_answer

Different namespaces are created at different times and have different lifetimes. Namespaces containing built-in names are created when the Python interpreter starts, and will remain until deleted.

The global namespace of the module is created when the module definition is read in. Usually, the module namespace is also saved until the interpreter exits.

The statement executed by the interpreter at the highest level, whether it is read from a script file or from an interactive input, is part of the __main__ module, so they also have their own namespace (built-in names are also included in a In the module, it is called builtins ).

When the function is called, it creates a local namespace for it and is removed when the function returns or throws an exception that is not handled inside the function. (Actually, it’s more appropriate to describe what happened in oblivion.) Of course, each recursive call has its own local namespace.

Related Article: Python For Machine Learning

Scope is a Python program that directly accesses the namespace’s body area. Direct access here means that an incorrect reference to a name tries to find it in the namespace. Although scopes are statically defined, they are dynamic when used. At least three namespaces that can be directly accessed by a namespace are nested together at each execution:

  • The domain containing the local name is used in the innermost, first search; second search is the middle scope, here contains the function of the same level;

    Finally search for the outermost scope, which contains built-in naming.

  • First search for the innermost scope, which contains the scope of the local named arbitrary function, is the starting point of the inner nested scope search, contains non-local, but also non-global named

  • The next scope contains the global name of the current module

  • The outermost scope (last search) contains built-in named namespaces

If a naming declaration is global, all references and assignments to it are directly searched for the scope containing the global naming of the module.

If you want to rebind variables outside the innermost scope, you can use nonlocal statements; if you don’t declare them nonlocal, these variables will be read-only (assigning to such a variable creates a new one in the innermost scope. Local variables, external variables with the same name will not change).

In general, local scope references the name of the current function. Outside of functions, local and global use domains refer to the same namespace: the module namespace. The class definition is also another namespace in the local scope.

The important thing is that the scope is determined by the meaning of the source program: It is important to understand that the global scope of a function defined in a module is the module’s namespace, rather than where the alias of the function is defined or invoked.

On the other hand, the actual search process for naming is dynamic and is determined at run time – however, the Python language is also evolving, and it may be determined statically later during “compilation,” so don’t rely on dynamic parsing! (In fact, local variables are already statically determined.)

One special thing about Python is that if you do not use the global syntax, its assignment operation is always at the innermost scope. Assignment does not copy the data, it just binds the name to the object.

The same is true for deletion: just remove the naming from the namespace of the local scope . In fact, all operations that introduce new names act on local scopes. In particular, import statements and function definitions bind module names or functions to local scopes (you can use the global statement to introduce variables into the global scope).del xx

The global statement is used to indicate that a particular variable is a global scope and re-bind it. The nonlocal statement is used to indicate that a particular variable is a closed scope and re-bind it.

Related Article: Python Data Structures

2.1. Examples of scopes and namespaces

The following is an example that shows how to reference different scopes and namespaces, and how global and nonlocal affect variable bindings:

DEF  scope_test (): 
    DEF  do_local (): 
        from spam  =  "local from spam" 
    DEF  do_nonlocal (): 
        nonlocal  from spam 
        from spam  =  "nonlocal from spam" 
    DEF  do_global (): 
        Global  from spam 
        from spam  =  "Global from spam" 
    from spam  =  "Test from spam" 
    do_local ( ) 
    print ( "After local assignment:" ,  spam ) 
    do_nonlocal () 
    print ( "After nonlocal assignment:" ,  spam ) 
    do_global() 
    print ( "After global assignment:" ,  spam )

Scope_test () 
print ( "In global scope:" ,  spam )

The output of the above sample code is:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

Note: The local assignment statement cannot change the spam binding of scope_test . nonlocal assignment changed scope_test of spam bindings, and global assignment changed from the module-level spam binding.

You can also see that spam is not pre-bound before the global assignment statement .

3. Python Class For Beginners

The class introduces some new syntax: three new object types and some new semantics.

3.1. Class Definition Syntax

The simplest form of class definition is as follows:

Class  ClassName : 
    < statement - 1 > 
    . 
    . 
    . 
    < statement - N >

The definition of a class is like a function definition ( def statement), which must be executed before it can take effect. (Of course you can put it in a branch of the if statement, or inside a function.)

Traditionally, the content of a class definition statement is usually a function definition, but other statements can be, sometimes useful, and we will come back to discuss it later. The definition of a function in a class usually includes a special form of a list of arguments for method invocation conventions – again we discuss these later.

After entering the class definition section, a new namespace is created as a local scope. Therefore, all assignments become local variables in this new namespace. In particular, the function definition is bound to the new name here.

When a class definition (normal exit), you create a class object . Basically it is a wrapper around the namespace created by the class definition; we will learn more about class objects in the next section.

The original local scope (the one that worked before the class definition was imported) is restored and the class object is bound here to the class name of the class definition header (in this example ClassName).

Related Article: Python Modules

3.2. Class Objects

Class objects support two operations: attribute references and instantiations.

Property References Use the same standard syntax as all property references in Python: obj.name. After the class object is created, all the names in the class namespace are valid attribute names. So if the class definition is this:

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

So MyClass.iand MyClass.fare valid attribute references, returning an integer and a method of the object. Class attributes can also be assigned to you can MyClass.imodify it a value. __doc__It is also a valid property that returns the class’s docstring: ."A simple example class"

Class instantiation uses function notation. Just think of the class object as a parameterless function that returns a new class instance. For example (assuming that the previous class is used):

x  =  MyClass ()

More than create a new class instance and the object is assigned to a local variable x.

This instantiation operation (“calling” a class object) creates an empty object. Many classes tend to create objects with an initial state. Therefore a class may define a named __init__()special method, like this:

Def  __init__ ( self ): 
    self . data  =  []

Class defines a __init__()method, then the class instantiation operator will call the new class instance is created automatically __init__()method. So in the following example, you can create a new instance like this:

x  =  MyClass ()

Of course, __init__()methods can have parameters for elasticity needs . In fact, the parameters __init__()passed to the class instantiation operator. E.g,

>>> class  Complex : 
...     def  __init__ ( self ,  realpart ,  imagpart ): 
...         self . r  =  realpart 
...         self . i  =  imagpart 
... 
>>> x  =  Complex ( 3.0 ,  - 4.5 ) 
>>> x . r ,  x . i 
(3.0, -4.5)

3.3. The Instance Object

What can we do now with instance objects? The only available action for an instance object is a property reference. There are two valid attribute names.

Data properties are equivalent to “instance variables” in Smalltalk or “data members” in C++. Like local variables, data properties do not need to be declared, and they will be generated the first time they are used.

For example, if xa previously created MyClassinstance, the following code will print out 16 while leaving extra stuff in the stack:

x . counter  =  1 
while  x . counter  <  10 : 
    x . counter  =  x . counter  *  2 
print ( x . counter ) 
del  x . counter

Another instance objects referenced attribute is accepted methods . A method is a function that belongs to an object. (In Python, methods are more than just class instances: other types of objects can also have methods.

For example, linked list objects have append, insert, remove, sort, etc. However, in the following description, unless otherwise specified , the method we mentioned specifically refers to the class method)

The valid name of an instance object depends on its class. By definition, all (user-defined) function objects in a class correspond to methods in its instance.

So in our example, x.fit is a valid method reference, since MyClass.fa function. But x.iit not, because MyClass.inot functions. However x.fand MyClass.fdifferent, it is a method of the object , not a function object.

Related Article: Python Input and Output

3.4. Method Objects

In general, methods are called by right-binding:

x . f ()

In the MyClassexample, this will return the string . However, it is not always necessary to call the method directly. Is a method object, it can be stored later call. E.g:'hello world'x.f

Xf  =  x . f 
while  True : 
    print ( xf ())

Will continue to print .hello world

What happened when the method was called? You may have noticed that call x.f()without an argument above marked time, although the f()function definition specifies a parameter.

What happened to this parameter? In fact, if there are missing parameters in the function call, Python throws an exception — even if this parameter is actually useless…

In fact, you may have guessed the answer: The special thing about the method is that the instance object is passed to the function as the first parameter of the function. In our example, the call x.f()is equivalent MyClass.f(x).

In general, calling a method with a list of n arguments is equivalent to inserting the object of the method into the front of the argument list, and then calling the corresponding function with this list.

If you still don’t understand how the method works, it may be helpful to understand its implementation. When you reference an instance attribute of a non-data attribute, it searches for its class.

If this name is confirmed as a valid function object class attribute, the instance object and function object will be encapsulated into an abstract object: this is the method object.

When a method object is called with a parameter list, it is reopened, a new parameter list is constructed with the instance object and the original parameter list, and then the function object calls this new parameter list.

3.5. Class and Instance Variables

In general, instance variables are used for unique data for each instance. Class variables are used for properties and methods shared by all instances of a class:

Class  Dog :

    Kind  =  'canine'          # class variable shared by all instances

    Def  __init__ ( self ,  name ): 
        self . name  =  name     # instance variable unique to each instance

>>>  d  =  Dog ( 'Fido' ) 
>>>  e  =  Dog ( 'Buddy' ) 
>>>  d . kind                   # shared by all dogs 
'canine' 
>>>  e . kind                   # shared by all dogs 
'canine' 
>>>  d . name                   # unique to d 
'Fido' 
>>>  e . name                   # unique to e 
'Buddy'

As terminology related discussion of variable objects, such as lists and dictionaries, shared data may bring unexpected results. For example, the list of tricks in the following code should not be used as a class variable because all Dog instances will share the same list:

Class  Dog :

    Tricks  =  []              # mistaken use of a class variable

    Def  __init__ ( self ,  name ): 
        self . name  =  name

    Def  add_trick ( self ,  trick ): 
        self . tricks . append ( trick )

>>>  d  =  Dog ( 'Fido' ) 
>>>  e  =  Dog ( 'Buddy' ) 
>>>  d . add_trick ( 'roll over' ) 
>>>  e . add_trick ( 'play dead' ) 
>>>  d . tricks                 # unexpectedly shared by all dogs 
[ 'roll over' ,  'play dead' ]

The correct design of this class should use an instance variable:

Class  Dog :

    Def  __init__ ( self ,  name ): 
        self . name  =  name 
        self . tricks  =  []     # creates a new empty list for each dog

    Def  add_trick ( self ,  trick ): 
        self . tricks . append ( trick )

>>>  d  =  Dog ( 'Fido' ) 
>>>  e  =  Dog ( 'Buddy' ) 
>>>  d . add_trick ( 'roll over' ) 
>>>  e . add_trick ( 'play dead' ) 
>>>  d . Tricks 
[ 'roll over' ] 
>>>  E . Tricks 
[ 'Play Dead' ]

Related Article: Python Errors and Exceptions

4. Some Instructions

Data properties override method properties with the same name. In order to avoid accidental name conflicts, this is a bug that is extremely difficult to find in large programs. It is wise to use some conventions to reduce the chance of conflicts. Possible conventions include: the first letter of the capitalization method name, using a unique small string (perhaps just an underscore) as a prefix for data attribute names, or methods that use verbs and data attributes that use nouns.

Data attributes can be referenced by methods, and can also be used by ordinary users (customers) of an object. In other words, classes cannot be used to implement pure data types. In fact, it’s impossible to force data to be hidden in Python — everything is based on conventions (If you need to, a Python implementation written in C can completely hide implementation details and control object access. This can be used to extend Python via C).

Customers should be cautious about using data attributes – customers may confuse constants that are maintained by methods by trampling on their data attributes. Note: As long as conflicts can be avoided, customers can add their own data attributes to an instance object without affecting the correctness of the method – again, naming conventions can avoid a lot of trouble.

There are no shortcuts to referencing data attributes (or other methods) from inside a method. I think this actually increases the readability of the method: When browsing a method, there is no puzzling situation between local variables and instance variables.

In general, the first parameter of the method is named self. This is just a convention: the Python, the name selfhas absolutely no special meaning. (However, please note: If you do not follow this convention, you will deteriorate the readability of the code to other Python programmers, and some class viewer program may also be prepared to follow this convention.)

Any function object of a class property defines a method for that class’s instance. The function definition code does not have to be defined in the class: it is also possible to assign a function object to a local variable in the class. E.g:

# Function defined outside the class 
def  f1 ( self ,  x ,  y ): 
    return  min ( x ,  x + y )

Class  C : 
    f  =  f1 
    def  g ( self ): 
        return  'hello world' 
    h  =  g

Now fgand hare class Cattributes, refer to function objects, so they are Cthe method of Example – hstrictly equal g. It should be noted that this habit usually only confuses the readers of the program.

By the selfmethod of attribute parameters, the method may call other methods:

Class  Bag : 
    def  __init__ ( self ): 
        self . data  =  [] 
    def  add ( self ,  x ): 
        self . data . append ( x ) 
    def  addtwice ( self ,  x ): 
        self . add ( x ) 
        self . add ( x )

Methods can refer to global names as if they were normal functions. The global scope associated with the method is the module that contains the class definition. (The class itself will never be used as a global scope.)

Although there are few good reasons to use global data in methods, global scope does have a lot of legitimate uses: one is that methods can call functions that import global scopes. And methods can also call the classes and functions defined in them.

Usually, the class that contains this method is also defined in this global scope. In the next section we will understand why a method has to reference its own class.

Each value is an object, therefore has a value for each class ( class ) (also referred to as its type ( type)), it is stored object.__class__.

5. Inheritance

Of course, if a language does not support inheritance, “class” does not make sense. The definition of a derived class is as follows:

Class  DerivedClassName ( BaseClassName ): 
    < statement - 1 > 
    . 
    . 
    . 
    < statement - N >

The naming BaseClassName(the base class name in the example) must be defined in a scope with the derived class. In addition to classes, you can also use expressions. This is useful when the base class is defined in another module:

Class  DerivedClassName ( modname . BaseClassName ):

The definition of the derived class is the same as the base class. When you construct a derived class object, you remember the base class. This is especially useful when parsing property references: if the requested property is not found in the class, it searches for the base class. If the base class is derived from another class, this rule will be applied recursively.

There is nothing special about the instantiation of a derived class: DerivedClassName()(The derived class in the column shown) creates a new class instance.

The method reference is parsed according to the following rules: Search for the corresponding class attribute, and if necessary, search along the base class chain step by step. If a function object is found, this method reference is legal.

Derived classes may override the methods of their base class. Because methods are not privileged when they call other methods in the same object, when the methods of the base class call the methods of the same base class, they may actually call the override method in the derived class. (For C ++ programmers, all methods in Python are essentially methods.)

The override method in a derived class might be to extend rather than simply replace the duplicate name method in the base class. There is a simple way to call the base class method directly: just call . Sometimes this is also useful for customers. (Note that only when the global scope defined or imported directly.)BaseClassName.methodname(self, arguments)BaseClassName

Python has two functions for inheritance:

  • Function the isinstance () to check the type instance: only is int or from other int type of inheritanceisinstance(obj, int)obj.__class__

  • Function issubclass () to check class inheritance: is because bool is int subclass.issubclass(bool, int)True

    However, it is because the float instead of int subclass.issubclass(float, int)False

5.1. Multiple Inheritance

Python also has limited support for multiple inheritance. Multi-inherited class definition is as follows:

Class  DerivedClassName ( Base1 ,  Base2 ,  Base3 ): 
    < statement - 1 > 
    . 
    . 
    . 
    < statement - N >

In most cases, in the simplest case, you can think of search attributes that inherit depth from parent classes first, left-to-right, instead of searching twice in the same class hierarchy, with one overlap.

Therefore, if DerivedClassNamean attribute is not found in the (derived class in the example), it searches Base1, then (recursively) searches for its base class, searches if it is not found, Base2and so on.

In fact, super() can dynamically change the parsing order. This approach can be seen in some other multi-inherit languages, similar to call-next-method, which is more powerful than super in single inheritance languages.

Dynamic ordering is necessary because all multiple inheritances have one or more diamond relationships (meaning that at least one ancestor class can be reached from a subclass via multiple inheritance paths). For example, all new-style classes inherit from object , so any multiple inheritance will always have more than one inheritance path to object .

In order to prevent repeated access to the base class, through a dynamic linearization algorithm, each class specifies the order in a left-to-right order. Each ancestor class is called only once, which is monotonic (meaning that a class is inherited. Does not affect the order of its ancestors). Finally, it is possible to design a reliable and scalable multi-inheritance class in this way.

6. Private variables

A “private” instance variable that can only be accessed from within the object does not exist in Python. However, there is also a workaround for most Python code: names that begin with an underscore (for example _spam) will be treated as a non-public part of the API (whether it is a function, method, or data member). It will be treated as an implementation detail and need not be exposed.

Because there is a legitimate class private member usage (that is, avoiding conflicting definitions in subclasses), Python provides limited support for this structure, called name mangling .

Any shape such as __spaman identification (underscores at least two front, a back up), is replaced _classname__spam, without the leading underscore classnameis the current class name. This grammar does not care about the location of the identifier, only within the class definition.

Name reorganization is useful for subclass override methods without breaking method calls within the group. E.g:

Class  Mapping : 
    def  __init__ ( self ,  iterable ): 
        self . items_list  =  [] 
        self . __update ( iterable )

    Def  update ( self ,  iterable ): 
        for  item  in  iterable : 
            self . items_list . append ( item )

    __update  =  update    # private copy of original update() method

Class  MappingSubclass ( Mapping ):

    Def  update ( self ,  keys ,  values ): 
        # provides new signature for update() 
        # but does not break __init__() 
        for  item  in  zip ( keys ,  values ): 
            self . items_list . append ( item )

It should be noted that the coding rules are designed to avoid conflicts as much as possible, and variables that are considered private may still be accessed or modified. It is also useful in specific situations, such as debugging.

Note that the code is passed exec()eval()without considering the class name called by class them as the current class, similar to the globaleffect of the statement has been compiled byte part has the same restrictions. This also applied to getattr()setattr()and delattr(), as a direct reference to __dict__the same.

7. Supplement

Sometimes useful for data types like “record” in Pascal or “struct” in C, it binds a set of named data items together. An empty class definition can do it well:

Class  Employee : 
    pass

John  =  Employee ()  # Create an empty employee record

# Fill the fields of the record 
john . name  =  'John Doe' 
john . dept  =  'computer lab' 
john . salary  =  1000

If a particular piece of Python code requires a special abstract data structure, it is usually possible to pass in a class. In fact, this mimics the method of the class.

For example, if you have a function for formatting data from a file object, you can define a having read()and readline()class methods, in order to read data from a string buffer instead, and the class as a parameter The function.

Examples of the method objects have attributes: m.__self__is an instance method belongs to an object, and m.__func__is a function of the object corresponding to the method.

8. Exceptions are also classes

User-defined exceptions can also be classes. Use this mechanism to create a scalable exception system.

The following are two new, valid (semantic) exception throwing forms using the raise statement:

Raise  Class

Raise  Instance

In the first form, it Classmust be an instance of type or its derived class. The second form is the following form of abbreviations:

Raise  Class ()

An exception occurs if its type is the class listed in the except clause, or is a derived class, then they are consistent (conversely – the type of exception that occurred if it is the basis of the class listed in the exception clause Class, they do not match). For example, the following code prints B, C, D sequentially:

Class  B ( Exception ): 
    pass 
class  C ( B ): 
    pass 
class  D ( C ): 
    pass

For  cls  in  [ B ,  C ,  D ]: 
    try : 
        raise  cls () 
    except  D : 
        print ( "D" ) 
    except  C : 
        print ( "C" ) 
    except  B : 
        print ( "B" )

It should be noted that if the order of the exception clause is reversed ( first), it will print B, B, B – the first matching exception is triggered.execpt B

When printing an exception class error message, the class name is printed first, followed by a space, a colon, and then the complete string converted by the built-in function str() .

9. Iterators

Now you may notice that most container objects can be traversed with for :

For  element  in  [ 1 ,  2 ,  3 ]: 
    print ( element ) 
for  element  in  ( 1 ,  2 ,  3 ): 
    print ( element ) 
for  key  in  { 'one' : 1 ,  'two' : 2 }: 
    print ( key ) 
for  char  in  "123" : 
    print ( char ) 
for  line In  open ( "myfile.txt" ): 
    print ( line ,  end = '' )

This form of access is clear, concise and convenient. The usage of iterators is universal and uniform in Python. In the background, the for statement calls iter() in the container object .

This function returns an iterator object that defines the __next__() method, which accesses the elements one by one in the container. When there is no subsequent element, __next__() throws a Stop Iteration exception notification for the end of the statement loop. You can call the __next__() method with the built-in next() function ; here’s an example of how it works:

>>> s  =  'abc' 
>>> it  =  iter ( s ) 
>>> it 
<iterator object at 0x00A1DB50> 
>>> next ( it ) 
'a' 
>>> next ( it ) 
'b' 
>>> Next ( it ) 
'c' 
>>> next ( it ) 
Traceback (most recent call last): 
  File "<stdin>" , line 1 ,In ? 
    next ( it ) 
StopIteration

Understanding the background mechanism of the iterator protocol makes it easy to add iterator behavior to your class. Define an __iter__() method to return an object with the __next__() method. If this class already has __next__() defined , __iter__() only needs to return self:

Class  Reverse : 
    """Iterator for looping over a sequence backwards.""" 
    def  __init__ ( self ,  data ): 
        self . data  =  data 
        self . index  =  len ( data ) 
    def  __iter__ ( self ): 
        return  self 
    def  __next__ ( self ): 
        if  self . index  ==  0 : 
            raise  StopIteration 
        self . index  = Self . index  -  1 
        return  self . data [ self . index ]
>>> rev  =  Reverse ( 'spam' ) 
>>> iter ( rev ) 
<__main__.Reverse object at 0x00A1DB50> 
>>> for  char  in  rev : 
...     print ( char ) 
... 
m 
a 
p 
s

10. Generator

Generator is a simple and powerful tool for creating iterators. They are written like regular functions and require the use of yield statements when returning data .

Each time next() is called, the generator reverts to the location it left off (it remembers where the statement was last executed and all data values). The following example demonstrates that the generator can be simply created:

Def  reverse ( data ): 
    for  index  in  range ( len ( data ) - 1 ,  - 1 ,  - 1 ): 
        yield  data [ index ]
>>> for  char  in  reverse ( 'golf' ): 
...     print ( char ) 
... 
f 
l 
o 
g

The class-based iterators described in the previous section can also be made by every thing that a generator can do. Because the __iter__() and __next__() methods are automatically created , the generator is so simple.

Another key feature is that between two executions, the local variables and the execution state are automatically saved. This function makes it easy to write, and than use self.indexand self.datamore clearly like fashion.

In addition to the automatic methods for creating and saving program state, StopIteration exceptions are automatically thrown when the generator terminates . In summary, these functions make writing a regular function the easiest way to create an iterator.

11. Generator Expressions

Sometimes a simple generator can be called in a succinct way, just like a linked list derivation without brackets. These expressions are designed for function call generators. Generator expressions are more concise than full generator definitions, but are not as varied and are often easier to remember than equivalent list comprehensions.

E.g:

>>> sum ( i * i  for  i  in  range ( 10 ))                  # sum of squares 
285

>>> xvec  =  [ 10 ,  20 ,  30 ] 
>>> yvec  =  [ 7 ,  5 ,  3 ] 
>>> sum ( x * y  for  x , y  in  zip ( xvec ,  yvec ))          # dot product 
260

>>> from  math  import  pi ,  sin 
>>> sine_table  =  { x :  sin ( x * pi / 180 )  for  x  in  range ( 0 ,  91 )}

>>> unique_words  =  set ( word   for  line  in  page   for  word  in  line . split ())

>>> valedictorian  =  max (( student . gpa ,  student . name )  for  student  in  graduates )

>>> data  =  'golf' 
>>> list ( data [ i ]  for  i  in  range ( len ( data ) - 1 ,  - 1 ,  - 1 )) 
['f', 'l', 'o', ' g']

Related Articles: 

Python Interview Questions

Python Programming Interview Questions

Leave a Comment