How to handle “duck typing” in Python?

前端 未结 5 820
生来不讨喜
生来不讨喜 2020-12-08 07:46

I usually want to keep my code as generic as possible. I\'m currently writing a simple library and being able to use different types with my library feels extra important th

5条回答
  •  离开以前
    2020-12-08 08:13

    First of all, the code in your question is not ideal:

    try:
        obj.wag_tail()
    except AttributeError:
        ...
    

    You don't know whether the AttributeError is from the lookup of wag_tail or whether it happened inside the function. What you are trying to do is:

    try:
        f = getattr(obj, 'wag_tail')
    except AttributeError:
        ...
    finally:
        f()
    

    Edit: kindall rightly points out that if you are going to check this, you should also check that f is callable.

    In general, this is not Pythonic. Just call and let the exception filter down, and the stack trace is informative enough to fix the problem. I think you should ask yourself whether your rethrown exceptions are useful enough to justify all of this error-checking code.

    The case of sorting a list is a great example.

    • List sorting is very common,
    • passing unorderable types happens for a significant proportion of those, and
    • throwing AttributeError in that case is very confusing.

    If those three criteria apply to your problem (especially the third), I agree with building pretty exception rethrower.

    You have to balance with the fact that throwing these pretty errors is going to make your code harder to read, which statistically means more bugs in your code. It's a question of balancing the pros and the cons.

    If you ever need to check for behaviours (like __real__ and __contains__), don't forget to use the Python abstract base classes found in collections, io, and numbers.

提交回复
热议问题