Object-oriented: reflection, double lower method

One. Reflection

The concept of reflection was first proposed by Smith in 1982, and it mainly means that the program can access, detect and modify its own state Or an ability of behavior (introspection). The proposal of this concept quickly led to research on applied reflectivity in the field of computer science. It was first adopted by the design field of programming language, and achieved achievements in Lisp and object-oriented.

Reflection in Python object-oriented: Manipulate object-related attributes in the form of strings. Everything in python is an object (reflection can be used)

Four functions that can achieve introspection

The following methods are applicable to classes and objects (everything is an object) , The class itself is also an object)

class Foo:
f ='Class static variables'
def __init__(self,name,age):
self.name =name
self.age=age

def say_hi(self):
print('hi,%s'%self.name)

obj=Foo('egon',73)

#Check whether it contains an attribute
print(hasattr(obj,'name'))
print(hasattr(obj,' say_hi'))

#Get attributes
n=getattr(obj,'name')
print(n)
func=getattr(obj,'say_hi' )
func()

print(getattr(obj,'aaaaaaaa','doesn't exist')) #Report an error

#Set attributes
setattr(obj,'sb',True)
setattr(obj,'show_name',lambda self:self.name+'sb')
print(obj.__dict__)
print(obj. show_name(obj))

#Delete attributes
delattr(obj,'age')
delattr(obj,'show_name')
delattr(obj,'show_name111 ')# does not exist, then an error will be reported

print(obj.__dict__)

Examples of instantiated objects
class Foo(object):< br /> 
staticField = "boy"

def __init__(self):
self.name ='a'

def func(self):
return'func'

@staticmethod
def bar():
return'bar'
print(getattr(Foo,'staticField'))
print(getattr(Foo,'func'))
print(getattr(Foo,'bar') )
import sys
def s1():
print('s1')

def s2():
print('s2 ')

this_module = sys.modules[__name__]
hasattr(this_module,'s1')
getattr(this_module,'s2')
# Code in a module
def test():
print('from the test')
"""
Program directory:
module_test.py
index.py

Current file:
index.py
"""
# Code in another module
import module_test as obj

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()< br />
Examples of other modules

Application of reflection:

class User:
def login(self):
print('Welcome Come to the login page')

def register(self):
print('Welcome to the registration page')

def sav e(self):
print('Welcome to the storage page')


while 1:
choose = input('>>>').strip ()
if choose =='login':
obj = User()
obj.login()

elif choose =='register':
obj = User()
obj.register()

elif choose =='save':
obj = User()
obj.save()
class User:
def login(self):
print('Welcome to the login page')

def register(self):
print('Welcome to the registration page')

def save(self):
print('Welcome to the save page')

user = User()
while 1:
choose = input('>>>').strip()
if hasattr(user,choose):
func = getattr(user, choose)
func()
else:
print('Input error. . . . ')

It’s easy to see at a glance.

two. function vs method

2.1 by printing function ( Method) name determination

def func():
pass

print(func) #


class A:
def func(self):
pass

print(A.func) #
obj = A ()
print(obj.func) # >

2.2 Verification by types module< /h4>

from types import FunctionType
from types import MethodType
def func():
pass
class A:
def func(self):< br /> pass
obj = A()

print(isinstance(func,FunctionType)) # True
print(isinstance(A.func,FunctionType)) # True< br />print(isinstance(obj.func,FunctionType)) # False
print(isinstance(obj.func,MethodType)) # True

2.3 static The method is a function

from types import FunctionType
from types import MethodType
class A:

def func(self):
pass

@classmethod
def func1(self):
pass

@staticmethod
def func2(self):
pass
obj = A()

# Static methods are actually functions
# print(isinstance(A .func2,FunctionType)) # True
# print(isinstance(obj.func2,FunctionType)) # True

2.4 The difference between function and method

(1) The function is to pass data explicitly. If you want to specify to pass some data to be processed for the len() function.

(2) Functions have nothing to do with objects.

(3) The data in the method is passed implicitly.

(4) The method can manipulate the data inside the class.

(5) Methods are related to objects. If you are using the strip() method, do you need to call it through the str object, such as the string s, and then call s.strip() like this. Yes, the strip() method belongs to the str object.

Maybe it is not rigorous when calling functions and methods colloquially in daily life, but you must know the difference between the two.

In other languages, such as Java only methods, C only functions, C++, it depends on whether it is in a class.

Three. Double Down Method

Definition: Double Down Method is a special method, which is provided by the interpreter by adding a cool underscore to the method name The method with special meaning with double underscore __method name__. The double download method is mainly used by python source code programmers. Try not to use the double download method in development, but it is more beneficial to our reading to study the double download method in depth. Source code.

Invoke: Different double-down methods have different triggering methods, just like the mechanism that is triggered when the tomb is robbed, the double-down method is triggered unknowingly, for example: init< /p>

3.01 len

class B:
def __len__(self):
print(666)
b = B()
len(b) # len An object will trigger the __len__ method.
class A:
def __init__(self):
self.a = 1
self.b = 2

def __len__(self):< br /> return len(self.__dict__)
a = A()
print(len(a))

3.02 hash

class A:
def __init__(self):
self.a = 1
self.b = 2

def __hash__( self):
return hash(str(self.a)+str(self.b))
a = A()
print(hash(a))

3.03 str

If the __str__ method is defined in a class, the return value of the method will be output by default when the object is printed.

class A:
def __init__(self):
pass
def __str__(self):
return'a'
a = A ()
print(a)
print('%s'% a)

3.04 repr

If the __repr__ method is defined in a class, the return value of the method will be output by default when repr(object).

class A:
def __init__(self):
pass
def __repr__(self):
return'a'
a = A ()
print(repr(a))
print('%r'%a)

3.05 call

Add parentheses after the object to trigger execution.

Note: The execution of the construction method __new__ is triggered by the creation of an object, namely: object = class name(); and the execution of the call method is added by the object Triggered by brackets, namely: object() or class()()

class Foo:

def __init__(self):
pass

def __call__(self, *args, **kwargs):

print('__call__')


obj = Foo() # Execute __init__
obj() # Execute __call__

3.06 eq

class A:
def __init__(self ):
self.a = 1
self.b = 2

def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b)

3.07 del

The destructor method automatically triggers execution when the object is released in memory.

Note: This method generally does not need to be defined, because Python is a high-level language, programmers do not need to care about the allocation and release of memory when using it, because this work is performed by the Python interpreter, so , The call of the destructor is automatically triggered by the interpreter during garbage collection.

3.08__new__

class A:
def __init__(self):
self.x = 1
print(' in init function')
def __new__(cls, *args, **kwargs):
print('in new function')
return object.__new__(A, *args, ** kwargs)

a = A()
print(ax)
class A:
__instance = None
def __new__(cls, * args, **kwargs):
if cls.__instance is None:
obj = object.__new__(cls)
cls.__instance = obj
return cls.__instance
Singleton mode is a commonly used software design mode. It contains only a special class called a singleton class in its core structure. Through the singleton mode, it can be ensured that there is only one instance of a class in the system and that the instance is easily accessible to the outside world, thus facilitating the control of the number of instances and saving system resources. If you want to have only one object of a certain class in the system, the singleton pattern is the best solution. 
[Motivation and reason for adopting singleton mode]
For some classes in the system, it is important to have only one instance. For example, there can be multiple print tasks in a system, but only one Tasks that are working; a system can only have one window manager or file system; a system can only have one timing tool or ID (serial number) generator. For example, only one task manager can be opened in Windows. If you do not use a mechanism to uniqueize the window object, multiple windows will pop up. If the content displayed in these windows is exactly the same, it is a duplicate object, wasting memory resources; if the content displayed in these windows is inconsistent, it means that at a certain moment The system has multiple states, which are inconsistent with the actual state, and will also cause misunderstandings to users, and they do not know which one is the real state. Therefore, it is sometimes very important to ensure the uniqueness of an object in the system, that is, a class can only have one instance.
How to ensure that there is only one instance of a class and this instance is easily accessible? Defining a global variable can ensure that the object can be accessed at any time, but it does not prevent us from instantiating multiple objects. A better solution is to make the class itself responsible for storing its only instance. This class can guarantee that no other instances are created, and it can provide a method to access the instance. This is the pattern motivation of the singleton pattern.
[Advantages and Disadvantages of Singleton Mode]
[Advantages]
One, instance control
Singleton mode prevents other objects from instantiating their own copies of singleton objects to ensure All objects have access to a unique instance.
Second, flexibility
Because the class controls the instantiation process, the class can change the instantiation process flexibly.
[Disadvantages]
1. Overhead
Although the number is small, if there is an instance of the class every time an object requests a reference, some overhead will still be required. This problem can be solved by using static initialization.
Two, possible development confusion
When using singleton objects (especially objects defined in a class library), developers must remember that they cannot use the new keyword to instantiate objects. Because library source code may not be accessible, application developers may accidentally find that they cannot instantiate this class directly.
Three, the object lifetime
can not solve the problem of deleting a single object. In languages ​​that provide memory management (such as languages ​​based on the .NET Framework), only a singleton class can cause an instance to be deallocated because it contains a private reference to the instance. In some languages ​​(such as C++), other classes can delete object instances, but this will cause floating references in singleton classes.

Specific analysis of singleton mode

3.09 __item__ series

class Foo:
def __init__(self,name):
self.name=name

def __getitem__ (self, item):
print(self.__dict__[item])

def __setitem__(self, key, value):
self.__dict__[key]=value< br /> def __delitem__(self, key):
print('del obj[key], I execute')
self.__dict__.pop(key)
def __delattr__(self, item):
print('del obj.key, I execute')
self.__dict__.pop(item)

f1=Foo('sb')
f1['age']=18
f1['age1']=19
del f1.age1
del f1['age']
f1['name' ]='a'
print(f1.__dict__)

enter exit

# If you want to perform the with as operation on an object of a class, it won’t work. 
class A:
def __init__(self, text):
self.text = text

with A('大爷') as f1:
print(f1.text)
class A:

def __init__(self, text):
self.text = text

def __enter__(self): # This method is triggered when the context manager object is opened
self.text = self.text +'You are here'
return self # Return the instantiated object to f1

def __exit__(self, exc_type, exc_val, exc_tb): # This method is triggered when the context manager object f1 is executed.
self.text = self.text +'This is going'

with A('Grandpa') as f1:
print(f1.text)
print(f1.text)
class Diycontextor:
def __init__ (self,name,mode):
self.name = name
self.mode = mode

def __enter__(self):
print "Hi enter here! !"
self.filehander = open(self.name,self.mode)
return self.filehander

def __exit__(self,*para):
print "Hi exit here"
self.filehander.close()

with Diycontextor('py_ana.py','r') as f:
for i in f:
print i

Leave a Comment

Your email address will not be published.