[Tutor] problem with a sub-class

Peter Otten __peter__ at web.de
Fri Dec 1 03:20:08 EST 2017


Alan Gauld via Tutor wrote:

> On 30/11/17 15:37, Shall, Sydney wrote:
> 
>> My problem is with constructing a sub-class.
>> 
>> My sub-class is constructed as follows:
>> 
>> import Population_ProductivityV24 as POCWP
> 
> Note that POCWP is an alias for the *module* Population_ProductivityV24.
> It is not a class.
> 
>> line 27 : class SimulateCycleZero(POCWP):
> 
> Here you define a class that subclasses your imported module.
> Frankly I'm surprised that you don't get an error there
> but hey...
> 
>> line 28 :     def __init__(self, dirname_p):
> 
> But this is now an init for a subclass of module.
> 
>> The error message is as follows:
>> 
>>    File
>> 
"/Users/sydney/AnacondaProjects/Capital/Capital_with_productivity/Current_Versions/Simulate_Cycle_Zero_V3.py",
>> line 27, in <module>
>>      class SimulateCycleZero(POCWP):
>> 
>> TypeError: module.__init__() takes at most 2 arguments (3 given)
> 
> So I'm guessing the use of a module to subclass
> has confused things and I confess I'm not clear on
> exactly what is going on and why you get this message.

A class is an instance of its metaclass.

class A:
    pass

is roughly equivalent to

A = type("A", (), {}) # classname, base classes, class attributes

and

class B(A):>>> class A:
...     def __init__(self, *args):
...         print("__init__{}".format(args))
... 
>>> class B(A()): pass
... 
__init__()
__init__('B', (<__main__.A object at 0x7f3db8a1c048>,), {'__module__': 
'__main__', '__qualname__': 'B'})
>>> assert isinstance(B, A)
>>> isinstance(B, A)                                                                                                                                                                                        
True                                                                                                                                                                                                               
>>> B()                                                                                                                                                                                                            
Traceback (most recent call last):                                                                                                                                                                                 
  File "<stdin>", line 1, in <module>                                                                                                                                                                              
TypeError: 'A' object is not callable                                                                                                                                                                              
    foo = 42

is roughly equivalent to

B = type(A)("B", (A,), {"foo": 42})

When you subclass from an instance of A instead of A itself this becomes

a = A()
B = type(a)("B", (a,), {"foo": 42})

which can be simplified to

B = A("B", (a,), {"foo": 42})

If this succeeds B is bound to an instance of A, but usually you'll see a 
TypeError, either immediately as the OP, 

>>> class A: pass
... 
>>> class B(A()): pass
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object() takes no parameters

or later when you try to instantiate B:

>>> class A:
...     def __init__(self, *args):
...         print("__init__{}".format(args))
... 
>>> class B(A()): pass
... 
__init__()
__init__('B', (<__main__.A object at 0x7f3db8a1c048>,), {'__module__': 
'__main__', '__qualname__': 'B'})
>>> isinstance(B, A)                                                                                                                                                                                        
True                                                                                                                                                                                                               
>>> B()                                                                                                                                                                                                            
Traceback (most recent call last):                                                                                                                                                                                 
  File "<stdin>", line 1, in <module>                                                                                                                                                                              
TypeError: 'A' object is not callable                                                                                                                                                                              

> But I'm pretty sure you don;t want to subclass your
> imported module and thats the mistake.




More information about the Tutor mailing list