Python object-oriented members

Posted by GameMusic on Sat, 08 Jan 2022 03:39:06 +0100

In the process of Python object-oriented programming, we instantiate the object for the class and access the corresponding resources in the class through the object pointer. These resources are roughly divided into three parts: fields, methods and attributes. We collectively refer to these three parts as class members.

1, Field

Fields can be divided into static fields and dynamic fields. The following code shows the two fields in the class

class MyClass:

# A static field belongs to a class. Multiple objects share a static field
leader = "abuve"

def __init__(self):
    # Dynamic fields belong to objects and can also be called ordinary fields. Each object will have its own unique dynamic fields
    self.name = "kevin"

Dynamic fields are very common in the instantiation process of classes. Each object encapsulates its own unique data through self. However, if all dynamic fields are used in the class, some unreasonable disadvantages will be encountered, such as the following code:

class Company:

def __init__(self, dept, leader):
    self.company_name = "Center"
    self.dept = dept
    self.leader = leader  
      
def ...

if name == "__main__":

it_dept = Company("IT", "Abuve")
hr_dept = Company("HR", "Kevin")

We encapsulate our own unique data for the object through dynamic fields, but here we find the company name company_ The name is "Center". No matter which department object is created, the company name remains unchanged. We know that the dynamic field is stored in the object, so each object contains a company_name field, which undoubtedly increases the memory overhead of the program. Therefore, a more reasonable way should use static fields. The code is as follows:

class Company:

company_name = "Center"

def __init__(self, dept, leader):
    self.dept = dept
    self.leader = leader    
    
def ...

if name == "__main__":

it_dept = Company("IT", "Abuve")
hr_dept = Company("HR", "Kevin")

At the same time, we should also follow some rules on the calling method of fields:
1. A static field belongs to a class, which is called and accessed through the class
2. A dynamic field belongs to an object and is accessed through an object

For the above code, we access the field data in the following way:

print it_dept.deptprint 
hr_dept.leaderprint 
Company.company_name

If you access a static field through an object, you can also access data, because the object also points to its own class through the object pointer, and the data not in the object will eventually be found in the class, but this call method is unreasonable.

Through the object call, the static fields of the class are also accessed

print it_dept.company_name

By adding two underscores in front of the field, you can set the field as a private field, for example:

class MyClass:

def __init__(self, name):
    self.__name = name 
    
def show(self):
    print self.__name
    

if name == "__main__":

object = MyClass("Abuve")    # Private fields cannot be accessed through objects
print object.__name    # Private fields are accessed through the internal methods of the class
object.show()    # It can also be accessed by adding an underscore before the class name
print object._MyClass__name

The last method also accesses private fields by adding an underscore before the class name, but in most cases, try not to access them in this way.

2, Method

In Python object-oriented programming, method calls are the most common. They are divided into dynamic methods (ordinary methods), static methods and class methods, which are shown in the code below.

class MyClass:

def __init__(self, name):
    self.name = name 
    
# Common method
def show(self):
    return self.name 
    
# Static method
@staticmethod
def detail(name):
    print '%s is good person.' %name 
    
# Dynamic method
@classmethod
def show_detail(cls):
    cls.detail('Kevin') 
    

if name == "__main__":

 object = MyClass("Jack")
 p_name = object.show()
 MyClass.detail(p_name)
 MyClass.show_detail()

As with fields, there are still some rules to follow in the invocation of methods.
1. Normal method, called by object
2. Static method, called by class
3. Class method is a kind of static method. It is called through class. When it is executed, the class name will be passed in automatically. Therefore, there should be a default receiving parameter.

Static methods can still be accessed through object pointers, but such calls are unreasonable. This slightly special method is written to a class because it has a certain correlation with the class.

3, Attributes

If the field belongs to the left and the method belongs to the right, the attribute belongs to the neutral, because it not only has the function of the method, but also can be accessed through the field. The following is a code segment containing the attribute.

class PageSet:

def __init__(self, count, page_size):
    self.count = count
    self.page_size = page_size 
    
# Insert the page through the decorator_ Num becomes an attribute, and there is no need to add parentheses when calling an object
@property
def page_num(self):
    page_count, remainder  = divmod(self.count, self.page_size)    
        
    if remainder == 0:
        return page_count
    else:
        return page_count + 1
    

if name == "__main__":

# The total number of incoming entries and the size of a single page
page_tools = PageSet(108, 10)    
# Page is executed as if it were a field_ Num method
print page_tools.page_num

The above code implements a page setting. We use the decorator property to set the page_ If the num method becomes an attribute, when the method is called by an object, it is like accessing a field, and there is no need to add parentheses. At this time, we only access methods through fields. Through the following code, we can also call relevant assignment and deletion actions for attributes.

class PageSet:

def __init__(self, count, page_size):
    self.count = count
    self.page_size = page_size 
    
@property
def page_num(self):
    page_count, remainder  = divmod(self.count, self.page_size)        
    
    if remainder == 0:           
        return page_count       
    else:            
        return page_count + 1

@page_num.setter
def page_num(self, value):
    print value        
    print 'This is set function.'

@page_num.deleter
def page_num(self):
    print 'This is delete function.'
    

if name == "__main__":

page_tools = PageSet(108, 10)    
# Call property to modify the property
page_tools.page_num    
# Call page_num.setter modifier attribute
page_tools.page_num = 12
# Call page_ Num.delete modifier attribute
del page_tools.page_num

4, Special member

Special members refer to special methods underlined on both sides of a function, which provide unique functions for a class.

1,__init__ 
Construction methods are the most common. When we instantiate a class, we use__ init__ The construction method encapsulates the data of the object.

2, __del__ 
Destructor, by__ del__ Function to construct a specific function. When performing del operation for an object, this part of the code can be called automatically. When the program executes relevant garbage collection, the destructor method can be applied.

3,__doc__   
Annotations, accessible through objects__ doc__ Function.

4,__module__ 
This method can display which module the current object belongs to.

5,__class__
This method displays which class the current object belongs to.

6,__call__ 
If we put parentheses after the instantiated object of the class, the call method in the class will be executed automatically.

class MyClass:

def __call__(self):
    print 'This is something...'
    

if name == "__main__":

object = MyClass()
object()

7,__str__
By default, only the memory address can be displayed when printing objects__ str__ You can display what you want to return.

class MyClass:

def __str__(self):
    return 'This is text that I want to return...'
    

if name == "__main__":

object = MyClass()    
print object

You can add the contents of two objects.

class MyClass:

def __init__(self, company, ceo):
    self.company = company
    self.ceo = ceo 
    
def __add__(self, other):
    return "%s---%s" %(self.company, other.ceo)
obj1 = MyClass("A","Abuve")
obj2 = MyClass("B", "Kevin")
print obj1 + obj2

The code finally printed "A---Kevin"

9,__dict__ 
Object calls this method to print out all encapsulated data, and class calls this access to print out all methods.

10,__getitem__,__setitem__,__delitem__
You can set corresponding execution actions for operating objects through dictionaries.

class MyClass(object):

def __getitem__(self, key):
    print '__getitem__',key 
    
def __setitem__(self, key, value):
    print '__setitem__',key,value 
    
def __delitem__(self, key):
    print '__delitem__',key 
    

if name == "__main__":

obj = Myclass()      
result = obj['k1']   # Yes__ getitem__ method
obj['k2'] = 'abuve'  # Yes__ setitem__ method
del obj['k1']   # Yes__ delitem__ method

11,__iter__
Used for iterators to return an object that can be iterated

class MyClass(object):

def __iter__(self):
    return iter([1,2,3,4,5]) 
    

if name == "__main__":

obj = MyClass()    
for i in obj:        
    print i

12,isinstance/issubclass
The type of an object can be determined through isinstance, and issubclass can determine whether two classes are inheritance

class Class1():

pass

class Class2(Class1):

pass

if name == "__main__":

obj = Class2()    # Judge whether the type of obj is Class2
print isinstance(obj, Class2)    # isinstance can also determine whether it inherits from the parent class
print isinstance(obj, Class1)    
print issubclass(Class2, Class1)

Topics: Python