I have a pair classes (Substance and Regime) that I'd like to hold lookup values for a common child class (Population), as shown. I want to make sure that instances of Population can only be created based on existing instances of the two parent classes Substance and Regime. My code (obviously) does not work the way I want, and I've been fiddling with this for a while, coming up with various BAD ideas: including global variables, breaking stuff into modules, spaghetti marinara everywhere! This seems like it should be easy to do in an explicit and direct way. Any ideas, please? (And no, I don't think multiple inheritance is correct here, but this was my latest try...)
class Substance:
def __init__(self, name):
self.name = name
class Regime:
def __init__(self, name):
self.name = name
class Population(Substance, Regime):
def __init__(self, subs, reg, qty):
self.subs = subs
self.reg = reg # this should validate against regime_dict
self.qty = qty
substance_dict = {'H' : substance('hydrogen'),
'C': substance('carbon')}
regime_dict = {'S1': regime('Surface 1'),
'S2': regime(Surface 2)}
pop = population('H', 'S1', 1000) # the first two args should validate against
# substance_dict and regime_dict
Why not just do this:
pop = population(substance_dict['H'], regime_dict['S1'], 1000)
That is, instead of passing in the labels of the substance and regime, pass in the actual substance and regime objects. You may have to adjust your code in Population
a bit to deal with this, because now it should expect a Subtance and a Regime, not two strings, but I think it will be much simpler conceptually.
If you need to enforce that Population
receives one Regime
and one Substance
, I'd try something like this:
class Substance(object):
def __init__(self, name):
self.name = name
class Regime(object):
def __init__(self, name):
self.name = name
class Population(object):
def __init__(self, subs, reg, qty):
if not isinstance(subs, Substance):
raise TypeError("subs must be a Substance")
if not isinstance(reg, Regime):
raise TypeError("reg must be a Regime")
self.subs = subs
self.reg = reg # this should validate against regime_dict
self.qty = qty
substance_dict = {'H' : Substance('hydrogen'),
'C': Substance('carbon')}
regime_dict = {'S1': Regime('Surface 1'),
'S2': Regime('Surface 2')}
pop = Population(substance_dict['H'], regime_dict['S1'], 1000)
pop_break = Population(substance_dict['H'], substance_dict['C'], 1000)
If you also want to verify that the arguments are in the dictionaries, then use something like this:
class Population(object):
def __init__(self, subs, reg, qty):
if not isinstance(subs, Substance):
raise TypeError("subs must be a Substance")
if not subs in substance_dict.values():
raise ValueError("subs %s is not in the substance_dict" % subs.name)
if not isinstance(reg, Regime):
raise TypeError("reg must be a Regime")
if not reg in regime_dict.values():
raise ValueError("reg %s is not in the regime_dict" % reg.name)
self.subs = subs
self.reg = reg # this should validate against regime_dict
self.qty = qty
substance_dict = {'H' : Substance('hydrogen'),
'C': Substance('carbon')}
regime_dict = {'S1': Regime('Surface 1'),
'S2': Regime('Surface 2')}
pop = Population(substance_dict['H'], regime_dict['S1'], 1000)
pop_break = Population(Substance('radon'), substance_dict['C'], 1000)
When you try to create pop_break, you'll receive an exception:
Traceback (most recent call last):
File "./stack7_1.py", line 29, in <module>
pop_break = Population(Substance('radon'), substance_dict['C'], 1000)
File "./stack7_1.py", line 14, in __init__
raise ValueError("subs %s is not in the substance_dict" % subs.name)
ValueError: subs radon is not in the substance_dict
Careful, because this will also break:
substance_dict = {'H' : Substance('hydrogen'),
'C': Substance('carbon')}
regime_dict = {'S1': Regime('Surface 1'),
'S2': Regime('Surface 2')}
pop = Population(substance_dict['H'], regime_dict['S1'], 1000)
pop_break = Population(Substance('hydrogen'), substance_dict['C'], 1000)
Since the Substance('hydrogen')
of the dictionary is a different instance than the Substance('hydrogen')
of the Population(Substance('hydrogen'), ... )
Try this:
class Population(Substance, Regime):
def __init__(self, subs, reg, qty):
#Etc...
ok, here is the right way to do what I wanted, thanks for your comments!
class Substance:
def __init__(self, symbol, name):
self.symbol = symbol
self.name = name
class Regime:
def __init__(self, symbol, name):
self.symbol = symbol
self.name = name
class Population(Substance, Regime):
def __init__(self, subs, reg, qty):
self.subs = subs
self.reg = reg # this should validate against regime_dict
self.qty = qty
self.key = subs.symbol+reg.symbol
s1 = Substance('H', 'hydrogen')
s2 = Substance('C', 'carbon')
reg = Regime('S1', 'Surface 1')
pop = Population(s1, reg, 1000)
print pop.subs.symbol
print pop.reg.symbol
print pop.key
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.