属性并从实例继承

时间:2013-08-13 00:02:41

标签: python oop properties

所以我通常不使用OOP,显然我不理解它,就像我想的那样。

假设我有一个(地理)状态的类:

class State(object):
    @property
    def population(self):
        return self._population
    @population.setter
    def population(self,value):
        if value < 0:
            raise ValueError("Population must not be negative")
        else:
            self._population = value

和一个几乎完全相同(刚才)的城镇课程:

class Town(State):
    @property
    def population(self):
        return self._population
    @population.setter
    def population(self,value):
        if value < 0:
            raise ValueError("Population must not be negative")
        else:
            self._population = value

现在假设我实例化一个State并给它一个特定的人口。我如何创建一个继承该State实例的人口的城镇实例? (暂时,我想 - 这只是一个例子。)或者我应该使用构图而不是继承?

我正在考虑的方式,这应该有效:

s = State()

s.population = 10

t = Town(s)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-141-00f052d998f0> in <module>()
----> 1 t = Town(s)

TypeError: object.__new__() takes no parameters

2 个答案:

答案 0 :(得分:3)

你不会说镇州(除非你住在新加坡或香港!)。但你会说一个州有一个镇。这表明构成。

请注意,默认情况下,State甚至没有population属性。所以从State继承并没有给Town任何属性:

class State(object):
    @property
    def population(self):
        return self._population
    @population.setter
    def population(self,value):
        if value < 0:
            raise ValueError("Population must not be negative")
        else:
            self._population = value

s = State()
print s.population

--output:--
raceback (most recent call last):
  File "1.py", line 13, in <module>
    print s.population
  File "1.py", line 4, in population
    return self._population
AttributeError: 'State' object has no attribute '_population'

所以当你说:

  

现在假设我实例化一个State并给它一个特定的人口。   我如何创建一个继承该州的城镇实例   实例的人口?

......这没有任何意义,因为Town类不了解任何State状态。给Town实例提供与State实例相同的人口的明显答案是:

class State(object):
    @property
    def population(self):
        return self._population
    @population.setter
    def population(self,value):
        if value < 0:
            raise ValueError("Population must not be negative")
        else:
            self._population = value

class Town(object):
    def __init__(self, population):
        self._population = population

    @property
    def population(self):
        return self._population

s = State()
s.population = 30
print s.population

t = Town(s.population)
print t.population

使用合成,你可以这样做:

class State(object):
    def __init__(self, name, *towns):
        self.name = name
        self.towns = towns 

    @property
    def population(self):
        total = 0
        for town in self.towns:
            total += town.population
        return total

class Town(object):
    def __init__(self, name, population):
        self._population = population

    @property
    def population(self):
        return self._population

    @population.setter
    def population(self,value):
        if value < 0:
            raise ValueError("Population must not be negative")
        else:
            self._population = value

detroit = Town("Detroit", 40)
lansing = Town("Lansing", 100)
detroit.population -= 10
print detroit.population
print lansing.population

s = State("Michigan", detroit, lansing)
print s.population

--output:--
30
100
130

答案 1 :(得分:1)

你现在所写的方式,你把城镇描述为一个国家,而一个国家不一定是一个城镇。也就是说,默认情况下,Town的行为与State完全相同,除非另有说明。

如果要将State传递给Town初始值设定项,则需要创建如下函数:

class Town(State):
    def __init__(self, state):
        self._population = state._population

在那之后,你不应该从你的例子中获得TypeError,它会表现出你的预期。