The Object Oriented 6.9: metaclass, reflection, the method bis
Moto类:
print(type('abc')) print(type(True)) print(type(100)) print(type([1, 2, 3])) print(type({'name': '太白金星'})) print(type((1,2,3))) print(type(object)) class A: pass print(isinstance(object,type)) print(isinstance(A, type))
type metaclass is to obtain the object belongs to a class, and type special class, Python principle is: everything is an object, in fact, classes can also be understood as 'objects', also known as class and type yuan to build classes, python majority built-in classes (including object) as well as their own definition of the class are created by the type metaclass.
And the relationship between the type classes and more unique object class: object is an instance of the class type, and the type is a subclass of the class of the object class, comparing the relationship expressed python magic can not be used in the code, which is defined as a must before further presence. So this only as understanding.
reflection:
Reflecting means can access the program, its ability to detect and modify the state itself or behavior (introspection)
python reflective object-oriented: the object-related properties operated by a string. Everything is an object in python (you can use reflection
Reflecting commonly used four functions:
class Student: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Student('alex',16) # hasatter 检测是否含有某属性,方法 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) 结果: True True # 获取属性,方法 # 获取不到直接报错 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() 结果: 'alex' 'hi,alex' # 设置属性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) 结果: {'name': 'alex', 'age': 16, 'sb': True, 'show_name': <function <lambda> at 0x00000180E591BB70>} alexsb # 删除属性 delattr(obj,'age') # delattr(obj,'show_name') # delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__) 结果: {'name': 'alex'}
Class reflection:
class Foo(object): staticField = "old boy" def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' @staticmethod def bar(): return 'bar' print(getattr(Foo, 'staticField')) print(getattr(Foo, 'func')) print(getattr(Foo, 'bar')) # 结果: old boy <function Foo.func at 0x00000212D21FBC80> # 获取func对象方法地址 <function Foo.bar at 0x00000212D21FBD08> # 获取bar静态方法地址
It reflected current module:
import sys def s1(): print('s1') def s2(): print('s2') this_module = sys.modules[__name__] print(hasattr(this_module, 's1')) print(getattr(this_module, 's2')) # 结果: True <function s2 at 0x000002000247BBF8>
Reflecting other modules:
import time print(hasattr(time,'ctime')) print(getattr(time,'ctime')) print(getattr(time,'ctime')()) # 结果: True <built-in function ctime> 'Fri Aug 9 08:12:54 2019'
Reflected Application
# 没学反射之前的解决方式: class User: def login(self): print('欢迎来到登录页面') def register(self): print('欢迎来到注册页面') def save(self): print('欢迎来到存储页面') 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()
Function with the difference method:
Determined by the print function (method) name
def func(): pass print(func) # <function func at 0x00000260A2E690D0> class A: def func(self): pass print(A.func) # <function A.func at 0x0000026E65AE9C80> obj = A() print(obj.func) # <bound method A.func of <__main__.A object at 0x00000230BAD4C9E8>>
Module types verified by
from types import FunctionType from types import MethodType def func(): pass class A: def func(self): pass obj = A() print(isinstance(func,FunctionType)) # True print(isinstance(A.func,FunctionType)) # True print(isinstance(obj.func,FunctionType)) # False print(isinstance(obj.func,MethodType)) # True
Static 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() # 静态方法其实是函数 print(isinstance(A.func2,FunctionType)) # True print(isinstance(obj.func2,FunctionType)) # True
The difference between the functions and methods
(1) function is a dominant parameter passing, a method is implicit parameter passing.
(2) function has nothing to do with the object.
(3) The method of operating data of the internal classes.
(4) method is associated with the object.
Double Down method:
Definition: The Double Down is a special method, he is an interpreter provided by the method name plus a double underscore double underlined __ method name has special significance __ method, the method is to double down python-source programmers, in try not to use development under the dual method, double underline known methods help us study the source code
1, only
class B: def __len__(self): print(666) b = B() len(b) # len 一个对象就会触发 __len__方法。 class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a))
2、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、str
If a class is defined __str__ method, then when the print target, the method returns the default output value.
class A: def __init__(self): pass def __str__(self): return '太白' a = A() print(a) print('%s' % a)
4、repr
If a class is defined __repr__ method, then at repr (object), the method returns a default output value.
class A: def __init__(self): pass def __repr__(self): return '太白' a = A() print(repr(a)) print('%r'%a)
5、call
Brackets behind the object, trigger the execution.
Note: the constructor is executed by the __new__ is triggered to create an object, namely: class name = Object (); For the call performed by the method of the object triggers the brackets, namely: Object () or class () ( )
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 执行 __init__ obj() # 执行 __call__
6、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)
7, the
Destructor, when the object is released in the memory, automatically trigger the execution.
Note: This method is generally no need to define, because Python is a high-level language, programmers used without concern allocate and free memory, because this work is to the Python interpreter to execute, so call the destructor is It triggered automatically performed at the time garbage collector by an interpreter.
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(a.x)
8、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(a.x)
Singleton:
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 pattern is a common software design patterns. In its core structure contains only a single embodiment is referred to a particular class category. Example ensures single mode systems only one instance of a class instance and the easy access to the outside, so as to facilitate control of the number of instances and save system resources. If you want a class of objects in the system can only be one, singleton pattern is the best solution.
[Single-case model motive, reason]
for certain types of systems, only one instance is important, for example, a system can contain multiple print job, but can only have a job are working; a system only You can have a window manager or a file system; a system can have a timing device or ID (number) generator. As in Windows, you can only open a task manager. If you do not use the mechanism of the window object uniquely, multiple windows pop up, if the contents of these windows display exactly the same, it is the duplicate object, a waste of memory resources; inconsistent content if the window is displayed, it means that in a moment the system has multiple states, inconsistent with the actual, misunderstanding will bring to the user, we do not know which one is the real state. So sometimes the system to ensure the uniqueness of an object that is a class only one instance is very important.
How to ensure that only one instance of a class, and this instance is easy to access it? Define a global variable can be sure that the object can be accessed at any time, but can not prevent us instantiate multiple objects. A better solution is to let the only instance of the class itself responsible for saving it. This class can ensure that no other instance is created, and it can provide a method to access the instance. This is the motivation mode Singleton pattern.
[Singleton] advantages and disadvantages
[advantage]
First, the control instance
Singleton pattern will prevent other objects instantiate a copy of its own singleton object, so as to ensure that all objects have access to a unique instance.
Second, the flexibility
because the control class instantiation process, so the flexibility to change the class instantiation process.
[Shortcomings]
First, overhead
Although few in number, but will check whether there are instances of the class if every object request references, would still require some overhead. Initialization can solve this problem by using static.
Second, the possible development of confusion
when using the singleton object (especially the objects defined in the class library), developers must keep in mind that they can not use the new keyword to instantiate an object. Because it may not access library source code, so application developers may find themselves unexpectedly can not be directly instantiated.
Third, object lifetime
can not solve the problem delete a single object. Providing memory management language (e.g., based on the language of the .NET Framework), can result in only a single instance of the class embodiment is unassigned because it contains a reference to the instance private. In some languages (e.g., C ++), other class instance object can be deleted, but this will lead to the suspension of the references appear singleton** 9, __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 def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
10 related context manager
enter exit
# 如果想要对一个类的对象进行with as 的操作 不行。 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): # 开启上下文管理器对象时触发此方法 self.text = self.text + '您来啦' return self # 将实例化的对象返回f1 def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法 self.text = self.text + '这就走啦' with A('大爷') as f1: print(f1.text)
Custom File Manager
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)
Related interview questions:
class StarkConfig: def __init__(self,num): self.num = num def run(self): self() def __call__(self, *args, **kwargs): print(self.num) class RoleConfig(StarkConfig): def __call__(self, *args, **kwargs): print(345) def __getitem__(self, item): return self.num[item] v1 = RoleConfig('alex') v2 = StarkConfig('太白金星') # print(v1[1]) # print(v2[2]) v1.run() ------- class UserInfo: pass class Department: pass class StarkConfig: def __init__(self, num): self.num = num def changelist(self, request): print(self.num, request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self, request): print(666, self.num) class AdminSite: def __init__(self): self._registry = {} def register(self, k, v): self._registry[k] = v site = AdminSite() site.register(UserInfo, StarkConfig) # 1 # obj = site._registry[UserInfo]() # 2 obj = site._registry[UserInfo](100) obj.run() ------- class UserInfo: pass class Department: pass class StarkConfig: def __init__(self,num): self.num = num def changelist(self,request): print(self.num,request) def run(self): self.changelist(999) class RoleConfig(StarkConfig): def changelist(self,request): print(666,self.num) class AdminSite: def __init__(self): self._registry = {} def register(self,k,v): self._registry[k] = v(k) site = AdminSite() site.register(UserInfo,StarkConfig) site.register(Department,RoleConfig) for k,row in site._registry.items(): row.run() ------- class A: list_display = [] def get_list(self): self.list_display.insert(0,33) return self.list_display s1 = A() print(s1.get_list()) ------- class A: list_display = [1, 2, 3] def __init__(self): self.list_display = [] def get_list(self): self.list_display.insert(0, 33) return self.list_display s1 = A() print(s1.get_list()) ------ class A: list_display = [] def get_list(self): self.list_display.insert(0,33) return self.list_display class B(A): list_display = [11,22] s1 = A() s2 = B() print(s1.get_list()) print(s2.get_list())