Question

What exactly does the last line of IClass do??

subclasscheck overloads subclasscheck but, normally while overloading an operator we do something like:

adt + 4.0 here, adt is the user defined type = user class object(instance) and 4.0 is a builtin type which has say .real, .imaginary pre-configured so if adt is complex then this becomes: adt.(self, other) add(self, other) so a reference to 'adt' is generated and fed to 'self' and 'other' refers to 4.0

But in the example below:

class IClass(object):
    def __init__(self):
        self.implementors = set()
    def register(self,C):
        self.implementors.add(C)
    def __instancecheck__(self,x):
        return self.__subclasscheck__(type(x))
    def __subclasscheck__(self,sub):
        return any(c in self.implementors for c in sub.mro())

# Now, use the above object
IFoo = IClass()
IFoo.register(Foo)
IFoo.register(FooProxy)

f = Foo()           # Create a Foo
g = FooProxy(f)     # Create a FooProxy
isinstance(f, IFoo)        # Returns True
isinstance(g, IFoo)        # Returns True
issubclass(FooProxy, IFoo) # Returns True

Here what are self and sub for subclasscheck?? How is subclasscheck being overloaded??

Anyway, assuming it is being overloaded somehow.. a reference to FooProxy is passed to self and IFoo->sub. So.. IFoo.mro() would generate the method resolution order for instance IFoo and therefore for IClass.. which would be just object.. umm.. wth??

Could somone explain what is going on here?? Basically 'any' should return True if FooProxy is a sub-class of the grouped-classes in IClass.

Was it helpful?

Solution

__subclasscheck__ is the method to override built-in issubclass. The call issubclass(X,Y) first checks whether Y.__subclasscheck__ exists, and if so, calls Y.__subclasscheck__(X) instead of its normal implementation.

similarly;__instancecheck__ is the method to override built-in isinstance. The call isinstance(X, Y) first checks whether Y.__instancecheck__ exists, and if so, calls Y.__instancecheck__(X) instead of its normal implementation.

In [121]: class FooProxy3(object):
     ...:     pass

In [122]: issubclass(FooProxy3,IFoo)
Out[122]: False

In [123]: for c in IFoo.implementors:
     ...:     print c
     ...:     
<class '__main__.Foo'>
<class '__main__.FooProxy'>

In [124]: for c in FooProxy3.mro():
     ...:     print c
     ...:     
<class '__main__.FooProxy3'>
<type 'object'>

In [125]: IFoo.register(FooProxy3)

In [126]: for c in IFoo.implementors:
     ...:     print c
     ...:     
<class '__main__.Foo'>
<class '__main__.FooProxy'>
<class '__main__.FooProxy3'>

In [127]: issubclass(FooProxy3,IFoo)
Out[127]: True

lets consider above example;create new class FooProxy3; and check issubclass for that; and it will return False (as per Out[122]) because we are looking for subclass check in IFoo.implementors; and there it is not present (as per In[123])
but when we have register FooProxy(here it means; now we can see it IFoo.implementors); we can see it Foxproxy3 in IFoo.implementors (as per In[126]) so when we check issubclass ; it wil return True.
for more info;
Customizing instance and subclass checks
Overloading isinstance() and issubclass()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top