YouTip LogoYouTip

Python Object

## Python2.x Object-Oriented Programming\\n\\nPython has been an object-oriented language since its design. Because of this, creating classes and objects in Python is straightforward. This chapter will provide a detailed introduction to object-oriented programming in Python.\\n\\nIf you haven't encountered object-oriented programming languages before, you might need to first understand some basic characteristics of object-oriented languages to form a foundational concept in your mind. This will help you learn Python's object-oriented programming more easily.\\n\\nNext, let's briefly understand some basic characteristics of object-oriented programming.\\n\\n* * *\\n\\n## Introduction to Object-Oriented Technology\\n\\n* **Class:** A collection of objects that share the same attributes and methods. It defines the common attributes and methods for all objects in that collection. An object is an instance of a class.\\n* **Class Variable:** A class variable is shared among all instances of the class. It is defined within the class but outside of any function body. Class variables are typically not used as instance variables.\\n* **Data Member:** A class variable or instance variable used to handle data related to the class and its instance objects.\\n* **Method Overriding:** If a method inherited from a parent class does not meet the needs of a child class, it can be modified. This process is called method overriding.\\n* **Local Variable:** A variable defined within a method, which only has scope within the current instance of the class.\\n* **Instance Variable:** In a class declaration, attributes are represented by variables. These variables are called instance variables and are declared within the class declaration but outside of its other member methods.\\n* **Inheritance:** A derived class inherits the fields and methods of a base class. Inheritance also allows treating an object of a derived class as an object of a base class. For example, consider a design where an object of type `Dog` is derived from the `Animal` class, simulating an "is-a" relationship (e.g., a Dog is an Animal).\\n* **Instantiation:** The creation of a specific instance of a class.\\n* **Method:** A function defined within a class.\\n* **Object:** An instance of a data structure defined by a class. An object includes two types of data members (class variables and instance variables) and methods.\\n\\n* * *\\n\\n## Creating a Class\\n\\nUse the `class` statement to create a new class, followed by the class name and a colon:\\n\\n```python\\nclass ClassName:\\n 'Class help information' # Class documentation string\\n class_suite # Class body\\n\\nThe class help information can be viewed via `ClassName.__doc__`.\\n\\n`class_suite` consists of class members, methods, and data attributes.\\n\\n### Example\\n\\nHere is a simple example of a Python class:\\n\\n```python\\nclass Employee:\\n 'Base class for all employees'\\n empCount = 0\\n\\n def __init__(self, name, salary):\\n self.name = name\\n self.salary = salary\\n Employee.empCount += 1\\n\\n def displayCount(self):\\n print "Total Employee %d" % Employee.empCount\\n\\n def displayEmployee(self):\\n print "Name : ", self.name, ", Salary: ", self.salary\\n\\n* The `empCount` variable is a class variable, and its value is shared among all instances of this class. You can access it using `Employee.empCount` from within or outside the class.\\n\\n* The first method, `__init__()`, is a special method known as the class constructor or initialization method. It is called when an instance of the class is created.\\n\\n* `self` represents the instance of the class. `self` is required when defining class methods, although it does not need to be passed as an argument when calling the method.\\n\\n### `self` Represents the Instance of the Class, Not the Class Itself\\n\\nThe only special distinction between a class method and a regular function is that they must have an extra **first parameter name**. By convention, this name is `self`.\\n\\n```python\\nclass Test:\\n def prt(self):\\n print(self)\\n print(self.__class__)\\n\\nt = Test()\\nt.prt()\\n\\nThe output of the above example is:\\n\\n__main__.Test\\n\\nFrom the output, it is clear that `self` represents the instance of the class (the address of the current object), while `self.__class__` points to the class.\\n\\n`self` is not a Python keyword; we can replace it with `tutorial` and it will still execute correctly:\\n\\n```python\\nclass Test:\\n def prt(tutorial):\\n print(tutorial)\\n print(tutorial.__class__)\\n\\nt = Test()\\nt.prt()\\n\\nThe output of the above example is:\\n\\n__main__.Test\\n\\n* * *\\n\\n## Creating Instance Objects\\n\\nInstantiation in other programming languages typically uses the `new` keyword, but Python does not have this keyword. Class instantiation is similar to a function call.\\n\\nThe following uses the class name `Employee` to instantiate and passes arguments via the `__init__` method:\\n\\n```python\\n"Create the first object of Employee class"\\nemp1 = Employee("Zara", 2000)\\n"Create the second object of Employee class"\\nemp2 = Employee("Manni", 5000)\\n\\n## Accessing Attributes\\n\\nYou can use the dot (`.`) operator to access object attributes. Use the class name to access class variables as follows:\\n\\n```python\\nemp1.displayEmployee()\\nemp2.displayEmployee()\\nprint "Total Employee %d" % Employee.empCount\\n\\nComplete example:\\n\\n```python\\nclass Employee:\\n 'Base class for all employees'\\n empCount = 0\\n\\n def __init__(self, name, salary):\\n self.name = name\\n self.salary = salary\\n Employee.empCount += 1\\n\\n def displayCount(self):\\n print "Total Employee %d" % Employee.empCount\\n\\n def displayEmployee(self):\\n print "Name : ", self.name, ", Salary: ", self.salary\\n\\n"Create the first object of Employee class"\\nemp1 = Employee("Zara", 2000)\\n"Create the second object of Employee class"\\nemp2 = Employee("Manni", 5000)\\nemp1.displayEmployee()\\nemp2.displayEmployee()\\nprint "Total Employee %d" % Employee.empCount\\n\\nThe output of the above code is:\\n\\nName : Zara ,Salary: 2000\\nName : Manni ,Salary: 5000\\nTotal Employee 2\\n\\nYou can add, delete, or modify class attributes as shown below:\\n\\n```python\\nemp1.age = 7 # Add a 'age' property\\nemp1.age = 8 # Modify 'age' property\\ndel emp1.age # Delete 'age' property\\n\\nYou can also access attributes using the following functions:\\n\\n* `getattr(obj, name[, default])`: Accesses the object's attribute.\\n* `hasattr(obj, name)`: Checks if an attribute exists.\\n* `setattr(obj, name, value)`: Sets an attribute. If the attribute does not exist, a new one is created.\\n* `delattr(obj, name)`: Deletes an attribute.\\n\\n```python\\nhasattr(emp1, 'age')\\ngetattr(emp1, 'age')\\nsetattr(emp1, 'age', 8)\\ndelattr(emp1, 'age')\\n\\n* * *\\n\\n* `__dict__`: The class's attributes (contains a dictionary composed of the class's data attributes).\\n* `__doc__`: The class's documentation string.\\n* `__name__`: The class name.\\n* `__module__`: The module where the class is defined (the class's full name is `'__main__.className'`; if the class is in an imported module `mymod`, then `className.__module__` equals `mymod`).\\n* `__bases__`: A tuple containing all base classes of the class.\\n\\nExamples of calling Python built-in class attributes:\\n\\n```python\\nclass Employee:\\n 'Base class for all employees'\\n empCount = 0\\n\\n def __init__(self, name, salary):\\n self.name = name\\n self.salary = salary\\n Employee.empCount += 1\\n\\n def displayCount(self):\\n print "Total Employee %d" % Employee.empCount\\n\\n def displayEmployee(self):\\n print "Name : ", self.name, ", Salary: ", self.salary\\n\\nprint "Employee.__doc__:", Employee.__doc__\\nprint "Employee.__name__:", Employee.__name__\\nprint "Employee.__module__:", Employee.__module__\\nprint "Employee.__bases__:", Employee.__bases__\\nprint "Employee.__dict__:", Employee.__dict__\\n\\nThe output of the above code is:\\n\\nEmployee.__doc__ : Base class for all employees\\nEmployee.__name__ : Employee\\nEmployee.__module__ : __main__\\nEmployee.__bases__ : ()\\nEmployee.__dict__ : {'__module__': '__main__', 'displayCount': , 'empCount': 0, 'displayEmployee': , '__doc__': 'xe6x89x80xe6x9cx89xe5x91x98xe5xb7xa5xe7x9ax84xe5x9fxbaxe7xb1xbb', '__init__': }\\n\\n* * *\\n\\n## Python Object Destruction (Garbage Collection)\\n\\nPython uses a simple technique called reference counting to track and recycle garbage.\\n\\nPython internally records how many references each object in use has.\\n\\nAn internal tracking variable, called a reference counter, is maintained.\\n\\nWhen an object is created, a reference count is created. When this object is no longer neededβ€”that is, when its reference count becomes 0β€”it is garbage collected. However, collection is not "immediate"; the interpreter reclaims the memory occupied by garbage objects at an appropriate time.\\n\\n```python\\na = 40 # Create Object \\nb = a # Increase reference, count\\nc = # Increase reference. count\\ndel a # Decrease reference count\\nb = 100 # Decrease reference count\\nc = -1 # Decrease reference count\\n\\nThe garbage collection mechanism not only targets objects with a reference count of 0 but also handles circular references. Circular references occur when two objects reference each other, but no other variables reference them. In this case, using reference counting alone is insufficient. Python's garbage collector is essentially a combination of a reference counter and a cyclic garbage collector. As a supplement to reference counting, the garbage collector also monitors objects that have been allocated a large amount of memory (i.e., those not destroyed via reference counting). In such cases, the interpreter pauses to attempt to clean up all unreferenced cycles.\\n\\n### Example\\n\\nThe destructor `__del__`, which is called when an object is destroyed, runs when the object is no longer in use:\\n\\n```python\\nclass Point:\\n def __init__(self, x=0, y=0):\\n self.x = x\\n self.y = y\\n\\n def __del__(self):\\n class_name = self.__class__.__name__\\n print class_name, "Destroy"\\n\\npt1 = Point()\\npt2 = pt1\\npt3 = pt1\\nprint id(pt1), id(pt2), id(pt3)\\ndel pt1\\ndel pt2\\ndel pt3\\n\\nThe output of the above example is:\\n\\n3083401324 3083401324 3083401324\\nPoint Destroy\\n\\n**Note:** Typically, you should define a class in a separate file.\\n\\n## Class Inheritance\\n\\nOne of the main benefits of object-oriented programming is code reuse. One way to achieve this is through the inheritance mechanism.\\n\\nA new class created through inheritance is called a **subclass** or **derived class**, and the class being inherited is called the **base class**, **parent class**, or **superclass**.\\n\\n**Inheritance Syntax**\\n\\n```python\\nclass DerivedClassName(BaseClassName):\\n ...\\n\\nSome characteristics of inheritance in Python:\\n\\n* 1. If the child class needs the constructor of the parent class, it must explicitly call the parent class's constructor, or not override the parent class's constructor. For detailed explanation, see: (#).\\n* 2. When calling a method of the base class, you need to prefix it with the base class name and include the `self` parameter variable. The difference is that when calling a normal function within a class, the `self` parameter is not required.\\n* 3. Python always looks for the corresponding method in the derived class first. If it cannot find it there, it then starts searching in the base class one by one. (First look for the method in the current class; if not found, then look in the base class).\\n\\nIf more than one class is listed in the inheritance tuple, it is called "multiple inheritance".\\n\\n**Syntax:**\\n\\nThe declaration of a derived class is similar to its parent class, with the list of inherited base classes following the class name, as shown below:\\n\\n```python\\nclass SubClassName (ParentClass1[, ParentClass2, ...]):\\n ...\\n\\n```python\\nclass Parent:\\n parentAttr = 100\\n\\n def __init__(self):\\n print "Call parent class constructor"\\n\\n def parentMethod(self):\\n print 'Call parent class method'\\n\\n def setAttr(self, attr):\\n Parent.parentAttr = attr\\n\\n def getAttr(self):\\n print "Parent class property :", Parent.parentAttr\\n\\nclass Child(Parent):\\n def __init__(self):\\n print "Call subclass constructor"\\n\\n def childMethod(self):\\n print 'Call subclass method'\\n\\nc = Child()\\nc.childMethod()\\nc.parentMethod()\\nc.setAttr(200)\\nc.getAttr()\\n\\nThe output of the above code is:\\n\\nCall subclass constructor\\nCall subclass method\\nCall parent class method\\nParent class property : 200\\n\\nYou can inherit from multiple classes:\\n\\n```python\\nclass A: # Define class A\\n .....\\nclass B: # Define class B\\n .....\\nclass C(A, B): # Inherit Classes A and B\\n .....\\n\\nYou can use the `issubclass()` or `isinstance()` methods to check.\\n\\n* `issubclass(sub, sup)`: A boolean function that checks if a class is a subclass or descendant of another class.\\n* `isinstance(obj, Class)`: A boolean function that returns true if `obj` is an instance of `Class` or an instance of a subclass of `Class`.\\n\\n* * *\\n\\n## Method Overriding\\n\\nIf the functionality of your parent class method does not meet your needs, you can override it in the child class:\\n\\nExample:\\n\\n```python\\nclass Parent:\\n def myMethod(self):\\n print 'Call parent class method'\\n\\nclass Child(Parent):\\n def myMethod(self):\\n print 'Call subclass method'\\n\\nc = Child()\\nc.myMethod()\\n\\nThe output of the above code is:\\n\\nCall subclass method\\n\\n* * *\\n\\n## Basic Overridden Methods\\n\\nThe following table lists some common functionalities that you can override in your own classes:\\n\\n| No. | Method, Description & Simple Call |\\n| --- | --- |\\n| 1 | **`__init__(self [,args...] )`** Constructor. Simple call: `_obj = className(args)_` |\\n| 2 | **`__del__(self )`** Destructor, deletes an object. Simple call: `_del obj_` |\\n| 3 | **`__repr__(self )`** Converts to a form readable by the interpreter. Simple call: `_repr(obj)_` |\\n| 4 | **`__str__(self )`** Converts to a human-readable string form. Simple call: `_str(obj)_` |\\n| 5 | **`__cmp__(self, x )`** Object comparison. Simple call: `_cmp(obj, x)_` |\\n\\n* * *\\n\\n## Operator Overloading\\n\\nPython also supports operator overloading, as shown in the following example:\\n\\n```python\\nclass Vector:\\n def __init__(self, a, b):\\n self.a = a\\n self.b = b\\n\\n def __str__(self):\\n return 'Vector (%d, %d)' % (self.a, self.b)\\n\\n def __add__(self, other):\\n return Vector(self.a + other.a, self.b + other.b)\\n\\nv1 = Vector(2, 10)\\nv2 = Vector(5, -2)\\nprint v1 + v2\\n\\nThe output of the above code is:\\n\\nVector(7,8)\\n\\n* * *\\n\\n## Class Attributes and Methods\\n\\n### Private Class Attributes\\n\\n**`__private_attrs`**: Starts with two underscores, declaring the attribute as private. It cannot be used or accessed directly outside the class. When used within methods inside the class, it is accessed as `self.__private_attrs`.\\n\\n### Class Methods\\n\\nInside a class, use the `def` keyword to define a method for the class. Unlike regular function definitions, class methods must include the `self` parameter, and it must be the first parameter.\\n\\n### Private Class Methods\\n\\n**`__private_method`**: Starts with two underscores, declaring the method as private. It cannot be called from outside the class. When called within the class, use `self.__private_methods`.\\n\\n```python\\nclass JustCounter:\\n __secretCount = 0\\n publicCount = 0\\n\\n def count(self):\\n self.__secretCount += 1\\n self.publicCount += 1\\n print self.__secretCount\\n\\ncounter = JustCounter()\\ncounter.count()\\ncounter.count()\\nprint counter.publicCount\\nprint counter.__secretCount\\n\\nPython changes the name to include the class name:\\n\\n1\\n2\\n2\\nTraceback (most recent call last):\\n File "test.py", line 17, in \\n print counter.__secretCount # Error, instance cannot access private variable\\nAttributeError: JustCounter instance has no attribute '__secretCount'\\n\\nPython does not allow instantiated classes to access private data, but you can use `object._className__attrName` (**object name._class name__private attribute name**) to access attributes. Refer to the following example:\\n\\n```python\\n#!/usr/bin/python\\n# -*- coding: UTF-8 -*-\\n\\nclass Tutorial:\\n __site = "example.com"\\n\\ntutorial = Tutorial()\\nprint tutorial._Tutorial__site\\n\\nThe output of the above code is:\\n\\nexample.com\\n\\n### Explanation of Single Underscore, Double Underscore, and Leading/Trailing Double Underscores:\\n\\n* **`__foo__`**: Defines a special method, usually a system-defined name, similar to `__init__()`.\\n\\n* **`_foo`**: Starts with a single underscore, indicating a protected type variable. This means it can only be accessed by the class itself and its subclasses, and cannot be used with `from module import *`.\\n\\n* **`__foo`**: Starts with a double underscore, indicating a private type variable. It can only be accessed by the class itself.
← Python Reg ExpressionsAtt String Min β†’