functional-style datatypes in Python
For anyone who's spent some time with sml, ocaml, haskell, etc. when you go back to using C, Python, Java, etc. you start to notice things you never knew were missing. I'm doing some stuff in Python and I realized what I really want is a functional-style datatype like (for example)
datatype phoneme = Vowel of string | Consonant of voice * place * manner
datatype voice = Voiced | Voiceless
datatype place = Labial | Dental | Retroflex | Palatal | Velar | Glottal
datatype manner = Stop | Affricate | Fricative | Nasal | Lateral
type syllable = 开发者_C百科phoneme list
Does anyone have a particular way that they like to simulate this in Python?
As sth indicated, your voice, place, and manner types are just enumerated types. There are a number of ways to implement those, such as
class voice(object):
Voiced, Voiceless = range(2)
Then you can refer to voice.Voiced and voice.Voiceless, and so forth.
The problem is types like phoneme. In C the usual way to implement something like that would be to hold your nose and use a union. In something like python, you use polymorphism. First, figure out what operations you're going to perform on the phoneme type. Then, implement those operations as member functions of a Vowel class and a Consonant class. In C++ you'd make those member functions virtual and make an abstract base class for Vowel and Consonant; in python you can get away without doing that thanks to duck typing, although you might still find a base class to be useful.
So,
class Vowel(object):
def SomeInitialMethod(self):
# ...
class Consonant(object):
def SomeInitialMethod(self):
# ...
p.SomeInitialMethod() # p can be either vowel or consonant
def SomeLaterFunction(p)
# p is assumed to be either a Vowel or a Consonant
if isinstance(p, Vowel):
# ...
elif isinstance(p, Consonant):
# ...
For the simple enumerations like voice
, place
and manner
you could use a class like this:
class Enum(object):
def __init__(self, *values):
self._values = set(values)
for value in values:
setattr(self, value, value)
def __iter__(self):
return iter(self._values)
place = Enum('Labial', 'Dental', 'Retroflex', 'Palatal', 'Velar', 'Glottal')
a = place.Retroflex
if a == place.Labial:
print "How did this happen?"
for p in place:
print "possible value:", p
You could create classes that contain the attributes you need.
class Phoneme:
# ...
class Consonant(Phoneme):
def __init__(self, voice, place, manner):
self.voice = voice
self.place = place
self.manner = manner
# ...
h = Consonant('Voiceless', 'Glottal', 'Fricative')
# ...
精彩评论