Python - 在不调用超级构造函数的情况下继承已经初始化的类

时间:2015-02-24 23:03:30

标签: python class oop inheritance constructor

我正在尝试创建一个Python gazetteer模块。我有以下课程:州,县和市。我需要一个国家了解所有县,一个县了解所有城市,一个城市了解其县和县。州。 (Python 3.x)

以下是我的内容:

class State(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

    def state_name(self):
        return self.state


class County(State):
    def __init__(self, state_class, **kwargs):
        self.__bases__ = (state_class, )
        self.__dict__.update(kwargs)


class City(County):
    def __init__(self, county_class, **kwargs):
        self.__bases__ = (county_class, )
        self.__dict__.update(kwargs)

然后我这样做:

fl = State(state='Florida', abb='FL', fips='12')
mdc = County(fl, county='Miami-Dade', fips='086')
setattr(fl, 'miami_dade', mdc)
rmd = City(mdc, city='Richmond', fips='60230')
setattr(mdc, 'richmond', rmd)


print(fl.state, fl.abb, fl.fips, fl.miami_dade.county, fl.miami_dade.richmond.city)
# Florida FL 12 Miami-Dade Richmond
print(fl.state_name())
# Florida
print(fl.__dict__)
# {'abb': 'FL', 'miami_dade': <__main__.County object at 0x0000000002C44A20>, 'fips': '12', 'state': 'Florida'}
print(fl.miami_dade.__dict__)
# {'__bases__': (<__main__.State object at 0x000000000358A048>,), 'fips': '086', 'county': 'Miami-Dade', 'richmond': <__main__.City object at 0x0000000002C44A90>}
print(fl.miami_dade.richmond.__dict__)
# {'fips': '60230', 'city': 'Richmond', '__bases__': (<__main__.County object at 0x0000000002C44A20>,)}
print(isinstance(fl.miami_dade.richmond, State))
# True

到目前为止一切都很好......但随后:

print(fl.miami_dade.richmond.state_name())
# AttributeError: 'City' object has no attribute 'state'

我希望我的City类使用State和County类中的方法。我最好的猜测是代码print(fl.miami_dade.richmond.state_name())正在使用City实例中的属性而不是State实例中的属性执行state_name()方法。

我不明白我在这里做错了什么。 County类甚至可以继承已经初始化的State类的方法和属性吗?

<小时/> 更多信息:
我不想在城市和县做super().__init__(),例如a = City('Seattle', 'King', 'Washington')因为以下原因。
我有56个州(包括美国领土),3,234个县和163,252个城市的数据。如果我让每个城市都有一个县和州的副本,这是浪费记忆。此外,我有每个县(约20MB)形成多边形的坐标,平均县有50个城市;如果每个城市都有副本,这就超过千兆。


好吧,这对我正在做的事情来说不是一个好的结构,我正在改变它,但是当我不明白的时候我不喜欢它。我想了解这里发生了什么。
以下是简化版:

class A:
    def __init__(self, name):
        self.name = name

    def getA(self):
        return self.name

class B(A):
    def __init__(self, aname, bname):
        self.name = bname
        super().__init__(aname)

b = B('AAA', 'BBB')
print(b.getA())
# AAA

好的,我觉得这很好。 但接着在这里:

class A2:
    def __init__(self, name):
        self.name = name

    def getA2(self):
        return self.name

class B2(A2):
    def __init__(self, A2Obj, name):
        self.__bases__ = (A2Obj, )
        self.name = name

a2 = A2('AAA2')
b2 = B2(a2, 'BBB2')
print(b2.getA2())
# BBB2
print(a2.name)
# AAA2

a2知道它的名字是AAA2。为什么b2.getA2()给我BBB2?就像b2继承了a2的方法而不是属性。如何让b2表现得像上面的例子?

1 个答案:

答案 0 :(得分:3)

你可能使用错误的结构:你的城市不是一个县,你的县不是一个州。 你应该使用组合而不是派生

class State(object):
  def __init__(self, **kwargs):
    self.__dict__.update(kwargs)

  def state_name(self):
    return self.state


class County(object):
  def __init__(self, state, **kwargs):
    self.state=state # this will just reference the state object
    self.__dict__.update(kwargs)
  def getStateName(self):
    return self.state.state


class City(object):
  def __init__(self, county, **kwargs):
    self.county = county
    self.__dict__.update(kwargs)
  def getStateName(self):
    return self.county.getStateName()

如果您希望以后能够在不跟踪对象的情况下检索它们,可以使用静态字典并在初始化期间添加创建的对象(例如“FL” - &gt; State(“Florida”))。然后添加一个静态方法来检索正确的对象。