1

Python, being dynamically typed, has no provision for type-hinting on method parameters. However, PHP, also being dynamically typed, does have a provision for type-hinting that a method parameter is at least an instance of a class (or that it is an instance of a class that inherits from a defined class).

public class Foo()
{
    public function __construct($qux, ...)
    {
        $this->qux = qux;
        ...
    }
}

public class Bar() 
{
    // "Type Hinting" done here enforcing 
    // that $baz is an instance of Foo
    public function __construct(Foo $baz, ...)
    {
        $this->baz = $baz;
        ...
    }
}

Is there a similar way of enforcing that a method param is a specific instance in Python?

If not, is the proper convention to simply assert?

class Foo(object):
    def __init__(self, qux=None, ...):
        self.qux = qux
        ...


class Bar(object):
    def __init__(self, baz=None, ...):
        # "Type Hinting" done here as `assert`, and
        # requires catch of AssertionError elsewhere
        assert isinstance(baz, Foo)

        self.baz = baz
        ...

If this is style of using assert is incorrect/inelegant/"not pythonic", what should I do instead?

3
  • I'd raise a TypeError exception, rather but your code looks good... Although be aware that isinstance will be True for all the child instances of Foo (you can enforce just Foo by doing type(baz) == Foo (no parenthesis on Foo) Commented Apr 14, 2014 at 22:08
  • 4
    Actually the Pythonic thing to do is use "duck typing"; if the value works, let it, regardless of whether it's the type you expect. That's why we talk of file like objects, sequences, etc - they're expected protocols, what Java would call interfaces, although they're not specified in the language. There is one type constraint built into the language, though; self on methods is type checked. Commented Apr 14, 2014 at 22:08
  • Today I would recommend using MyPy to check type annotations. Commented Oct 14, 2019 at 20:55

2 Answers 2

4

Not out of the box. You can, however, combine parameter annotations with function decorators to almost effortlessly write your own.

Keep in mind, however, that the whole idea of duck typing is to avoid this kind of logic.

Sign up to request clarification or add additional context in comments.

Comments

2

There is a strong convention in Python to embrace the Duck Typing idiom, which in this case would mean that you would call the appropriate attributes from the baz object without explicitly checking its type. This has many benefits, including better support for polymorphism and arguably more readable / less verbose code.

If you tried to access an attribute which the object does not support, a AttributeError exception is raised. Therefore you could place this inside a try/except block and catch any AttributeError when appropriate - this is characteristic of another Python idiom called 'Easier to ask forgiveness than permission'

try:
    baz.foo
except AttributeError:
    # handle the exception

Some other questions that cover this topic

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.