1

For example take a simple class representing a person. The only class attribute is a string representing the persons name. I want to make sure that nobody tries to pass the constructor some other type of object like an int, or list...etc. This was my first attempt below I thought that this would return an obj of type None if the argument was not a str but it still seems to return a Person obj. I come from a "more" strongly typed language background and I am a little confused as how to handle my self in python. What does pythonic style say about this situation and type safety more generally? Should I raise an exception? Or find a way to return None? Or something else entirely.

class Person: 

    name = None

    def __init__(self, name):
        if not isinstance(name, str):
            return None
        self.name = name
2
  • 1
    I essentially made a similar question the other day, and you can find it here. I urge you to read Martijn Pieter's answer as it is very related to what you ask. Commented Dec 18, 2012 at 16:36
  • Why not use self.name = str(name)? That would accept everything that has a string representation. Commented Dec 18, 2012 at 17:03

3 Answers 3

6

You'd want to raise an error within the __init__ method:

if not isinstance(name,basestring):
    raise TypeError("I don't think that is a name ...")

*Note that basestring also includes unicode for python2.x, but isn't available in python3.x.

Careful though, there is nothing here to prevent a user from re-setting the person's name to a list after the person has been constructed.

jack = Person("Jack")
jack.name = ["cheese","steak"]  #???

If you want to have this safety built in, you'll need to start learning about property.

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

7 Comments

@JonClements -- Yeah, I suppose so. Good call. :)
OMG - that's scary - we both just added that at the same time :) (the str/basestring thing that is) - Good point about properties though + 1:)
@JonClements -- We seem to have hive mind for this question. We posted simultaneously as well...
@RocketDonkey -- I forgot to add the line : isintance = isinstance at the top ;-)
@vanattab -- Basically, yes. The idea is that if the variable acts like a duck, and smells like a duck, and looks like a duck, then it must be a duck.
|
5

That's about it - short of using some form of decorator, but generally, type checking isn't very Pythonic, although valid in some cases, your code should be:

def __init__(self, name):
    if not isinstance(name, basestring):
        raise TypeError('name must be str/unicode')
    # ...

Note that basestring is the parent of str and unicode in Python 2.x, so this would allow both - either use str (as you are now in 2.x) to not allow unicode (or vice versa - for any particular reason). In 3.x, basestring doesn't exist, you've just got str.

2 Comments

+1 for mentioning that "type checking isn't [usually] very Pythonic"
@vanattab Further reading that might be useful: stackoverflow.com/questions/1950386/…
0

I would not return None here but rather raise and exception to signify the incorrect object type.

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.