3

Possible Duplicate:
python: class override “is” behavior

I am trying to override the is operator, so that I could do something like

if tom is writer:
   print 'tom is writing'
elif tom is programmer:
   print 'tom is programming'

Is this possible in python?

Community
  • 1
  • 1
satoru
  • 31,822
  • 31
  • 91
  • 141
  • 1
    Do you mean "is", or "isa"? This looks like "isa" to me. – Josephine Nov 12 '10 at 01:28
  • Assuming "tom" in your example is an object, you can't just get away with methods like tom.is_writer() and tom.is_programmer()? – uzi Nov 12 '10 at 01:30
  • @uzi In my case, `writer` and `programmer` are jobs and there are too many of them to be implemented in the class of tom. Currently I am using something like `tom.works_as_a(writer)`. – satoru Nov 12 '10 at 01:36
  • Recommend you just replace works_as_a() with is_a(). Don't override things that are that fundamental to the language. – Russell Borogove Nov 12 '10 at 01:40

2 Answers2

5

As far as I know, you can't override 'is' because it tests whether two objects are the same object by comparing their memory addresses (i.e. pointer comparison). You probably want to override '==' by implementing tom's __eq__ method.

codewarrior
  • 2,000
  • 14
  • 14
3

The Python way to test for the type of an object is to use isinstance, as in isinstance(tom,Writer).

But whenever you start to write code that reads like your example, think about using polymorphism instead. Here is a simple class hierarchy that does what you want, without a single call to isinstance:

class Worker(object):
    def __init__(self, name):
        self.name = name

    def is_doing(self):
        return "working"

class Writer(Worker):
    def is_doing(self):
        return "writing"

class Programmer(Worker):
    def is_doing(self):
        return "programming"

workers = [
    Writer("Tom"),
    Programmer("Dick"),
    ]

for w in workers:
    print "%s is %s" % (w.name, w.is_doing())

Prints:

Tom is writing
Dick is programming

Now you can just add new subclasses to Worker and implement is_doing, and you don't have to maintain some table of type-to-activity values.

This pattern of polymorphism is traditional O-O, but in Python, you aren't even restricted to subclasses of Worker - any object that implements is_doing and has a name attribute will work:

class Fish(object):
    def __init__(self, n):
        self.name = n
    def is_doing(self):
        return "swimming"

workers.append(Fish("Wanda"))

for w in workers:
    print "%s is %s" % (w.name, w.is_doing())

will print:

Tom is writing
Dick is programming
Wanda is swimming
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
  • Thx. But polymorphism won't work for me, because the entities that I called `job` is not exactly jobs. And a person can have multiple entities of such kind at the same time. – satoru Nov 12 '10 at 03:29