I'm migrating some code from Python 2 to Python 3, and I am getting different behaviour. Looking through the lists of "what's changed" hasn't pointed me to any relevant differences, but presumably I've missed a big one.
I have simplified my code as much as possible to get this 'minimal faulty program':
def decorator(Type):
""" This is a class decorator. It replaces a class with a subclass which
*should be* equivalent.
The result works on Python 2.7 but not on Python 3.4. """
class FactorySubclass(Type):
""" This subclasses from the provided type, and overrides the __new__
and __init__ methods, but replaces them with exact equivalents,
so I can't see how this has any effect. """
def __new__(cls, *args, **kwargs):
# Simplified this code to do basically nothing.
# If this line is removed, it works on both versions.
return Type.__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
# Simplified this code to do basically nothing.
Type.__init__(self, *args, **kwargs)
return FactorySubclass
@decorator
class ExampleClass(object):
def __init__(self, param=3):
print("Constructed example instance")
ec = ExampleClass(param=5)
This code runs, and prints Constructed example instance
in Python 2.7.
This code fails, and dumps a stack trace in Python 3.4.
Traceback (most recent call last):
File "mfp.py", line 31, in <module>
ec = ExampleClass(param=5)
File "mfp.py", line 16, in __new__
return Type.__new__(cls, *args, **kwargs)
TypeError: object() takes no parameters
Typically this error means that someone has misspelled __init__
(and so constructor parameters are bypassing the relevant class and being given to object
's parameterless constructor, but that doesn't seem to be the case here.
Oh, and as an afterthought, I confirmed that, yes, the value of param
was 5 in Python 2.7.
2to3
gives it a clean-bill of health.
Please give me a pointer to a change in Python 3 that would invalidate this code, so I may read more about it.
__init__ Method with No Parameter __init__ method can be used with no parameter. In this case, the values of the instance will be set to the default values or nothing will be done.
Yes—functions are objects in Python and, like all objects, can be passed as arguments into functions and methods. No special syntax is needed.
If a function takes no parameters, the parameters may be left empty. The compiler will not perform any type checking on function calls in this case. A better approach is to include the keyword "void" within the parentheses, to explicitly state that the function takes no parameters.
The Python "TypeError: Class() takes no arguments" occurs when we forget to define an __init__() method in a class but provide arguments when instantiating it. To solve the error, make sure to define the __init__() (two underscores on each side) method in the class. Here is an example of how the error occurs.
You have the answer in your question:
Typically this error means [...] constructor parameters are [...] being given to object's parameterless constructor [...]
To fix, change your decorator to only add __init__
and __new__
if the passed-in Type
has those methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With