Unsupported operand type(s) for +: 'NoneType' and 'str'

In the book << professional python >> (author: Luke Sneeringer) page3-page4 (or say page33-page34)

def decorated_by(func):
    func.__doc__ +=  '\nDecorated by decorated_by.'
    return func

def add(x,y):
    return x+y

add = decorated_by(add)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in decorated_by
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'str'

My python version:

python3 --version
Python 3.11.2

How to fix it?

Your add function is different from the one in the book, which is why the decorator function is not working for you. Can you spot the difference?

I can’t spot the difference,please tell me why in detail.

The books version is 3 lines long, your version is 2 lines long.

The difference is this line:

"""Return the sum of x and y."""

which is present in the example but missing from your function. It is a docstring. A common misconception is that docstrings are comments; this is not the case. Docstrings are part of your program and (usually) exist at runtime.

The docstring of an object is stored in the object’s __doc__ attribute. If the object has no docstring, this attribute is None.

The decorated_by function tries to add a string to a function’s existing docstring. If the input function does not have a docstring, as in your case, this fails because a str cannot be added to None.

1 Like

Try (untested)

def decorated_by(func):
    if func.__doc__ is not None:
        func.__doc__ +=  '\nDecorated by decorated_by.'
    else:
        func.__doc__ =  'Decorated by decorated_by.'
    return func

The decorator in the book assumes that its argument will already have some docstring, and it appends a string to that value. It does not expect to create a docstring for a function that lacks one.

1 Like