Abstract base class

import abc

class Person(metaclass=abc.ABCMeta): Can only be inherited, can not be instantiated, instantiation error
@abc.abstractmethod # Modified methods must be overridden
    def eat(self):
        pass

    @abc.abstractmethod
    def drink(self):
        pass
  
Copy the code

In order to solve Python2&3 compatibility problems, we need to introduce the six module, which has a class-specific decorator @sex.add_metaclass (MetaClass) that can easily add MetaClass to both versions of Python classes

import abc
import six


@six.add_metaclass(abc.ABCMeta)
class Person(object):
    @abc.abstractmethod
    def eat(self):
        pass

    @abc.abstractmethod
    def drink(self):
        pass
Copy the code

Object comparison (isinstance and Type)

Type () doesn’t think that a subclass is a superclass type. Isinstance () does think that a subclass is a superclass type. Isinstance can tell if an instance of a subclass belongs to a superclass; Type accepts only one parameter. You can not only determine whether the variable belongs to a type, but also obtain the unknown type of the parameter variable. However, isinstance can only determine whether the variable belongs to a known type and cannot directly obtain the type of the unknown variable

# coding=UTF-8
>>> a = 4
>>> isinstance (a,int)
True
>>> isinstance (a,str)
False
>>> isinstance (a,(str,int,list))# same as one of the tuple types
True
>>> isinstance(a,(str,list,float))Is not the same as the tuple type
False
Copy the code
# coding=UTF-8
class father(object):
    pass
class son(father):
    pass
>>>a=father()
>>>b=son()
>>>isinstance(a,father)
True
>>>type(a)==father
True
>>>isinstance(b,father)#isinstance gets a subclass instance that belongs to the parent class
True
>>>type(b)==father#type does not belong to the parent class for subclass instances
 False
Copy the code
# coding=UTF-8
class A(object):
    pass
>>>a=A()
#type Determines whether a variable is of a type
>>>type(a)==A
True
#type gets the type of the variable
>>>type(a)
 __main__.A
#isinstance can only determine if a variable is of a type
>>>isinstance(a,A)
True
Copy the code

Class and instance attributes and the order in which they are found

After Python2.2, BFS(breadth first search) was introduced. After Python2.3,Python adopted the C3 algorithm, which can obtain the order of lookup through mrO ()


Introspection mechanism

The ######dir() dir() function is probably the most famous part of Python’s introspection mechanism. It returns an sorted list of property names for any object passed to it. If no object is specified, dir() returns the name of the current scope.

type()

The type() function helps us determine whether the object is a string or an integer, or some other type of object. It does this by returning a type object that can be compared to a type defined in the Types module

hasattr()

The object has attributes, and the dir() function returns a list of those attributes. However, sometimes we just want to test for the presence of one or more attributes. If the object has a property that we are considering, we usually want to retrieve only that property. This task can be accomplished by the hasattr() and getattr() functions.

isinstance()

You can use the isinstance() function to test an object to determine if it is an instance of a particular type or custom class


Derive built-in immutable types and modify the instantiation behavior

class IntTuple(tuple):
    def __new__(cls, *args, **kwargs):
        f = (i for i in args if isinstance(i, int) and (i > 0))
        return super().__new__(cls, f)
Copy the code

Creating a large number of instances saves memory

In python’s new classes, you can define a variable __slots__, which prevents instances from being assigned dict when instantiating classes. By default, each class has a dict, accessed through __dict__, which maintains all attributes of the instance. Since a new dict is allocated every time a class is instantiated, there is a waste of space, hence __slots__. __slots__ is a tuple containing the currently accessible attributes. When slots is defined, the variables defined in slots become class descriptors, equivalent to member variable declarations in Java and c++. Instances of classes can only have the variables defined in slots, and no new variables can be added. Note: With slots defined, there is no longer dict

class Person(object):
    __slots__ = ('name'.'age')

    def __init__(self):
        self.name = "None"
        self.age = 10
Copy the code

Note that attributes defined by __slots__ apply only to the current class, not to inherited subclasses


The with statement in Python

with open('image.png'.'r') as f:
  f.read()
Copy the code
Contextlib simplifies the context manager
class OpenContext(object):
    def __init__(self, filename, mode):
        self.fp = open(filename, mode)

    def __enter__(self):
        return self.fp

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.fp.close()

if __name__ == '__main__':
    with OpenContext('abc.txt'.'w') as file:
        file.write("hello world")
Copy the code

Classes can be decorated with @ContextManager

from contextlib import contextmanager

@contextmanager
class OpenContext(object):
    def __init__(self, filename, mode):
        fp = open(filename, mode)
        print("file open")
        try:
            yield fp
        finally:
            fp.close()
Copy the code

Create manageable object properties

You can use property to manage properties

class Person:
    def __init__(self):
        self.__age = 10

    def age(self):
        return self.__age

    def set_age(self, age):
        if not isinstance(age, int):
            raise TypeError("TypeError")
        self.__age = age

    def del_age(self):
        self.__age = None

    age = property(fget=age, fset=set_age, fdel=del_age)

if __name__ == '__main__':
    p = Person()
    p.age = 33
    print(p.age)
Copy the code

Let the class support comparison operations

from functools import total_ordering

@total_ordering
class Rect(object):
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(self):
        return self.w * self.h

    def __lt__(self, other): # override less than method, can automatically implement greater than method
        return self.area() < other.area()

    def __eq__(self, other): # equals method
        return self.area() == other.area()
Copy the code

Manage memory in a circular data structure

The reference count does not increase after using WeakRef modification

import weakref

a = A()
a2 = weakref.ref(a)
Copy the code

Python garbage collection mechanism

Gets the memory usage method
import os
import psutil

Display the size of memory currently occupied by Python programs
def show_memory_info(hint):
    pid = os.getpid()
    p = psutil.Process(pid)
    
    info = p.memory_full_info()
    memory = info.uss / 1024. / 1024
    print('{} memory used: {} MB'.format(hint, memory))
Copy the code
Circular reference resolution

Getting reference relationships

import objgraph

a = [1, 2, 3]
b = [4, 5, 6]

a.append(b)
b.append(a)

objgraph.show_refs([a])
Copy the code

Objgraph.show_refs (d, filename= ‘sample-graph.png’) dot

Clears objects that are not referenced

import gc

gc.collect() # clear memory
Copy the code