Python object-oriented programming,
Isinstance (obj, cls) and issubclass (sub, super)
Isinstance (obj, cls) checks whether obj is a cls-like object
1 class Foo(object):2 pass3 4 obj = Foo()5 6 isinstance(obj, Foo)
Issubclass (sub, super) checks whether the sub class is a derived class of the super class
class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)
Ii. Reflection
2 reflection in python object-oriented: operations on Object-related attributes in the form of strings. Everything in python is an object (reflection can be used)
Four functions for introspection
Def getattr (object, name, defalut = None ):
Determines whether the object has a method or attribute corresponding to the name string.
def getattr(object, name, default=None): # known special case of getattr """ getattr(object, name[, default]) -> value Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y. When a default argument is given, it is returned when the attribute doesn't exist; without it, an exception is raised in that case. """ pass
Def setattr (x, y, v ):
def setattr(x, y, v): # real signature unknown; restored from __doc__ """ Sets the named attribute on the given object to the specified value. setattr(x, 'y', v) is equivalent to ``x.y = v'' """ pass
Def delattr (x, y ):
def delattr(x, y): # real signature unknown; restored from __doc__ """ Deletes the named attribute from the given object. delattr(x, 'y') is equivalent to ``del x.y'' """ pass
Practice Cases
Class BlackMedium: feature = 'ugg' def _ init _ (self, name, addr): self. name = name self. addr = addr def sell_house (self): print. name) def every _house (self): print ('% s black intermediary rent a house. It's silly to rent it' % self. name) b1 = BlackMedium ('Ten thousand lands ', 'longguan tianlu jiayuan') # check whether a certain attribute print (hasattr (b1, 'name') (hasattr (b1, 'prop _ House') # obtain the attribute n = getattr (b1, 'name') print (n) func = getattr (b1, 'rent _ House') func () # getattr (b1, 'aaaaaaa') # print (getattr (b1, 'aaaaaaaaa', 'nonexistent A') # Set the property setattr (b1, 'SB ', True) setattr (b1, 'show _ name', lambda self: self. name + 'SB ') # Add the sb attribute print (b1. _ dict _) print (b1.show _ name (b1) to Blackhouser # Delete the attribute delattr (b1, 'addr ') delattr (b1, 'show _ name') delattr (b1, 'show _ name111') # print (b1. _ dict __)
Class is also an object
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 ')
#!/usr/bin/env python# -*- coding:utf-8 -*-import sysdef s1(): print 's1'def s2(): print 's2'this_module = sys.modules[__name__]hasattr(this_module, 's1')getattr(this_module, 's2')
#!/usr/bin/env python# -*- coding:utf-8 -*-def test(): print('from the test')
1 #! /Usr/bin/env python 2 #-*-coding: UTF-8-*-3 4 "5 program Directory: 6 module_test.py 7 index. py 8 9 current file: 10 index. py11 "12 13 import module_test as obj14 15 # obj. test () 16 17 print (hasattr (obj, 'test') 18 19 getattr (obj, 'test ')()
View Code
3. Why is reflection benefits?
Benefit 1: Implement pluggable Mechanism
In short, the advantage of reflection is that you can define the interface in advance, and the interface will be actually executed only after it is completed, which implements plug-and-play, this is actually a kind of 'post-binding '. What does it mean? That is, you can write the main logic (only define interfaces) in advance, and then implement the interface functions later.
Class FtpClient: 'ftp client, but there are still some specific functions 'def _ init _ (self, addr ): print ('connecting to server [% s]' % addr) self. addr = addr
# From module import FtpClientf1 = FtpClient ('2017. 168.1.1 ') if hasattr (f1, 'get'): func_get = getattr (f1, 'get') func_get () else: print (' ----> this method does not exist ') print ('process other logics ')
Dynamic import module
3__ setattr __,__ delattr __,__ getattr __
Class Foo: x = 1 def _ init _ (self, y): self. y = y def _ getattr _ (self, item): print ('----> from getattr: the property you are looking for does not exist') def _ setattr _ (self, key, value): print ('----> from setattr') # self. key = value # This is infinite recursion. Think about it # self. _ dict _ [key] = value # Use def _ delattr _ (self, item): print ('----> from delattr') # del self. item # infinitely recursive self. _ dict __. pop (item) #__ setattr _ adding/modifying properties will trigger its execution f1 = Foo (10) print (f1. _ dict __) # Because you have rewritten _ setattr __, any value assignment operation will trigger its operation. You did not write anything, that is, there is no value assignment at all, unless you directly operate the attribute dictionary, otherwise, the value f1.z = 3 print (f1. _ dict _) will never be assigned __) #__ delattr _ When deleting an attribute, f1. _ dict _ ['a'] = 3 # You can directly modify the attribute dictionary, del f1.aprint (f1. _ dict _) #__ getattr _ triggers f1.xxxxxx only when you use a vertex to call a property and the property does not exist.
Standard four-step processing (packaging)
Packaging: python provides you with standard data types and rich built-in methods. In fact, in many scenarios, We need to customize our own data types based on standard data types, add/Rewrite methods, which use the inherited/derived knowledge we just learned (other standard types can be processed through the following method)
Authorization: authorization is a feature of packaging. Packaging A type is usually customized for existing types. In this way, you can create, modify, or delete functions of the original product. Others are kept as they are. The authorization process is that all updated functions are processed by a part of the new class, but existing functions are authorized to the default attributes of the object.
The key to implementing authorization is to overwrite the _ getattr _ method.
Import timeclass FileHandle: def _ init _ (self, filename, mode = 'R', encoding = 'utf-8'): self. file = open (filename, mode, encoding = encoding) def write (self, line): t = time. strftime ('% Y-% m-% d % t') self. file. write ('% s % s' % (t, line) def _ getattr _ (self, item): return getattr(self.file,item1_f11_filehandle(' B .txt', 'W + ') f1.write ('hello, ') f1.seek (0) print (f1.read () f1.close ()
Note:
A descriptor itself should be defined as a new type class, and the class to be proxies should also be a new type class.
Second, the descriptor must be defined as the class attribute of this class, and cannot be defined in the constructor.
3. Strictly follow this priority. The priority ranges from high to bottom.
1. class attributes
2. Data Descriptor
3. instance attributes
4. Non-data Descriptor
5. Unable to find the property trigger _ getattr __()
Where
Data Descriptor and data descriptor: At least _ get _ () and _ set _ () are implemented __()
Non-data descriptor, not implemented _ set __()