about 'setattr(o, name, value)' and 'inspect.signature(f)'

Paul Moore p.f.moore at gmail.com
Tue Oct 10 11:15:50 EDT 2017


On 10 October 2017 at 15:37, xieyuheng <xyheme at gmail.com> wrote:
> 1. 'setattr(o, name, value)' can be used for what kind of objects ?
>
>    section '2. Built-in Functions'
>    of the official documentation says :
>
>    > The function assigns the value to the attribute, provided the object allows it.

Anything for which o.<name> = value will work. However, user defined
types can choose to raise an exception if you try to assign to certain
attributes, types with slots will raise an exception if you try to
assign to an attribute not defined in __slots__, etc.

These are all run-time behaviours, and so there's no way you can check
for them ahead of time. If you want to be sure setattr is allowed, you
need to handle possible exceptions:

    try:
        setattr(o, name, value)
    except Exception:
        # deal with the problem

Example:

>>> class C:
...     __slots__ = ['a', 'b']
...
>>> c = C()
>>> c.c = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'c'
>>> setattr(c, 'c', 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'c'
>>> try:
...     setattr(c, 'c', 1)
... except AttributeError:
...     pass
...
>>>

> 2. what kind of functions does not have signature,
>    so that 'inspect.signature(f)' can be used for them ?
>
>    section '29.12.3. Introspecting callables with the Signature object'
>    of the official documentation says :
>
>    > Some callables may not be introspectable in certain implementations of Python.
>    > For example, in CPython, some built-in functions defined in C
>    > provide no metadata about their arguments.
>
>    this is depends on implementation, so I ask for CPython.

Again, it's a runtime issue, so the answer is the same "it's easier to
ask for forgiveness than permission" - try the operation and handle
any exception:

>>> import inspect
>>> inspect.signature(type)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\me\AppData\Local\Programs\Python\Python36\Lib\inspect.py",
line 3033, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "C:\Users\me\AppData\Local\Programs\Python\Python36\Lib\inspect.py",
line 2783, in from_callable
    follow_wrapper_chains=follow_wrapped)
  File "C:\Users\me\AppData\Local\Programs\Python\Python36\Lib\inspect.py",
line 2262, in _signature_from_callable
    skip_bound_arg=skip_bound_arg)
  File "C:\Users\me\AppData\Local\Programs\Python\Python36\Lib\inspect.py",
line 2087, in _signature_from_builtin
    raise ValueError("no signature found for builtin
{!r}".format(func))
ValueError: no signature found for builtin <class 'type'>
>>> try:
...     sig = inspect.signature(type)
... except ValueError:
...     sig = None
...
>>> print(repr(sig))
None

Paul



More information about the Python-list mailing list