Unification of Methods and Functions

Donn Cave donn at drizzle.com
Thu May 6 01:46:35 EDT 2004


Quoth David MacQuigg <dmq at gain.com>:
...
| The second problem with the "avoidance/denial" strategy is that it
| involves moving the troublesome functions outside of the class
| definition.  This results in a less-than-optimal structure for your
| program.  Look at the show() methods in Animals_2.py  They must be
| callable without any specific instance.  Moving them outside the
| appropriate classes is not good programming.  When you want to change
| a class later, you will need to remember to look in some other place
| for any "static methods" associated with the class.
|
| If you could do me one more favor, please take a look at the
| Animals_2.py example starting on page 7 of the Prototypes document at
| http://ece.arizona.edu/~edatools/Python  Can you write this in Python?
| Give it a try, and let me know if you had any difficulties.  Were
| there any parts you had to stop and think, or look up in a manual?

Mine came out 66 lines, most of it very introductory level
and nothing exotic.  The first dozen lines deal with the
inventory problem, which I gather is the issue you're interested
in.  I don't maintain a count in each class, but rather keep
the counts in a single data structure in the base class, and
I provide a single show() function that prints them.  If I were
writing this in C++, I might make that a static function.
But then, I hate C++.

Now, you could argue that I changed the problem to suit my
purposes, but your approach repeats some stuff all over the
class hierarchy in a kind 'similar but not quite the same'
way that I don't like at all.  If we need to implement some
functionality that's general to the hierarchy, then let's
implement it once.  I can imagine in principle the need for
a class specific function.  In such a case, I would define
the function above the class definition, and refer to it
inside a data structure at the class level.  I have a vague
notion that there are newer Python features that address
these issues, but I'm not interested - it isn't important.

	Donn Cave, donn at drizzle.com
-----------------------------------
def show():
	for k, v in Animal.inventory.items():
		if v == 1:
			f = '%s: %s'
		else:
			f = '%ss: %s'
		print f % (k, v)

class Animal:
	home = 'Earth'
	inventory = {}
	def __init__(self):
		self.register('Animal')
	def register(self, name):
		i = self.inventory.get(name, 0)
		self.inventory[name] = i + 1

class Reptile(Animal):
	pass

class Mammal(Animal):
	def __init__(self, sound = 'Maa... Maa...'):
		self.sound = sound
		self.register('Mammal')
		Animal.__init__(self)
	def talk(self):
		print 'Mammal sound: ', self.sound

class Bovine(Mammal):
	pass

class Canine(Mammal):
	pass

class Feline(Mammal):
	genus = 'feline'
	def __init__(self):
		Mammal.__init__(self)
		self.register('Feline')

class Cat(Feline):
	def __init__(self, name='unknown', sound='Meow'):
		Feline.__init__(self)
		self.register('Cat')
		self.name = name
		self.sound = sound
	def talk(self):
		print 'My name is ...', self.name
		print 'I am', self.genus, 'from', self.home
		Mammal.talk(self)

a = Animal()
m = Mammal()
print 'm:',
m.talk()
f = Feline()
print 'f:',
f.talk()
c = Cat()
print 'c:',
c.talk()

show()

cat1 = Cat('Garfield', 'Purr')
cat1.talk()



More information about the Python-list mailing list