Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: object() takes no parameters - but only in Python 3

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.

like image 297
Oddthinking Avatar asked Oct 30 '14 12:10

Oddthinking


People also ask

What is the correct syntax for defining and method that takes no parameters?

__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.

Can an object be a parameter in Python?

Yes—functions are objects in Python and, like all objects, can be passed as arguments into functions and methods. No special syntax is needed.

How do you call a function with no parameters?

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.

What does takes no argument mean in Python?

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.


1 Answers

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.

like image 160
Ethan Furman Avatar answered Oct 25 '22 05:10

Ethan Furman