Python descriptors and inheritance

Asked
Active3 hr before
Viewed126 times

5 Answers

pythondescriptors
90%

If you inherit a class without __slots__, then the subclass will contain __dict__,,Descriptor methods include __get__(), __set__() and __delete__()

Example_snippet/controller/utility/_python.js/ __dict__. . .
__dict__
load more v
88%

We finally come now to our simple descriptor example in the following code:,The details above show that the mechanism for descriptors is embedded in the __getattribute__() methods for object, type, and super(), Classes inherit this machinery when they derive from object or if they have a meta-class providing similar functionality

Example_snippet/controller/utility/_python.js/ class A: ca_A = "clas. . .
class A:

   ca_A = "class attribute of A"

def __init__(self):
   self.ia_A = "instance attribute of A instance"

class B(A):

   ca_B = "class attribute of B"

def __init__(self):
   super().__init__()
self.ia_B = "instance attribute of A instance"

x = B()

print(x.ia_B)
print(x.ca_B)
print(x.ia_A)
print(x.ca_A)
load more v
72%

Custom validators need to inherit from Validator and must supply a validate() method to test various restrictions as needed,,The last section has pure Python equivalents for built-in descriptors that are written in C

Example_snippet/controller/utility/_python.js/ class Ten: def __get__(sel. . .
class Ten:
   def __get__(self, obj, objtype = None):
   return 10
load more v
65%

Subclasses will inherit descriptors from their parent class hierarchy, so self,A will be available on ChildClass2 if A is a class attribute

Example_snippet/controller/utility/_python.js/ class MyDescriptorClass(object. . .
class MyDescriptorClass(object):
   def __init__(self, activates = 0):
   self.value = None
self.activates = activates
self.connects = []

def __set__(self, instance, val): # 1
if self.value == val:
   return 0
self.value = val
if self.activates:
   instance.evaluate()
def __get__(self, instance, instcls): # 1
return self.value
Step 2 continued with class GateInput(object): d. . .
class GateInput(object):
   def __init__(self, index):
   self.index = index # 4

def __get__(self, inst, instcls):
   return inst.inputs[self.index].ans # 5

def __set__(self, inst, val):
   if isinstance(val, (float, int)):
   inst.inputs[self.index] = Constant(val)
else :
   inst.inputs[self.index] = val

class Constant(object):
   def __init__(self, val):
   self.ans = val

class Gate(object):
   A = GateInput(0) # 1
B = GateInput(1) # 1

def __init__(self, name):
   self.name = name
self.inputs = [Constant(0), Constant(0)] # 2

class Adder(Gate):
   @property
def ans(self):
   result = 0
for gate in self.inputs:
   result += gate.ans # 3
return result

class Multiplier(Gate):
   @property
def ans(self):
   result = 1
for gate in self.inputs:
   result *= gate.ans
return result

b = Multiplier('b1')
b.A = 2
b.B = 3
print(b.A)
# 2
print(b.ans)
# 6

c = Adder('c1')
c.A = 10
print(c.ans)
# 10

# This connects output of b to an input of c
c.B = b
print(c.ans)
# 16
load more v
75%

And the secret now is to use this list to register the descriptors, We can add the following to MyDescriptor:,The class to use this descriptor would be the same as before:,If we look at the list of descriptors, we will see that they are both the same:,Before we continue, it is also important to refresh how we can set and get attributes to an object:

Example_snippet/controller/utility/_descriptors.js/ class MyClass: _var = 0 . . .
class MyClass:
   _var = 0

@property
def
var (self):
print('Getting Var')
return self._var
load more v