2012-02-27 3 views
0

ABC에서 상속 된 인스턴스 변수에 대해 약간 혼동합니다. 나는 나의 혼란을 보여주는 모범을 보았습니다. 클래스 A는 클래스 B가 상속하는 목록을 필요로하지만 클래스 객체가 아닌 인스턴스 객체 여야합니다. 그러나 클래스 B는 자체 인스턴스 변수 local도 필요합니다. 누구든지 나를 똑바로 세울 수 있니?추상 기본 클래스에서 상속 된 객체를 혼동합니다.

#!python 
from abc import ABCMeta, abstractmethod, abstractproperty 
import unittest 

class A(object): 

    __metaclass__ = ABCMeta 
    _internal = ['initialized'] 

    @property 
    def internal(self): 
     return self._internal 

    def get_a(self): 
     return self._internal 

    @abstractmethod 
    def set_a(self, value): 
     pass 

class B(A): 
    def __init__(self): 
     self.local = 'OK' 


    def get_local(self): 
     return self.local 

    def set_a(self, value): 
     self._internal.append(value) 


class TestCase(unittest.TestCase): 

    def test_implementation(self): 
     self.assertEqual(['initialized'], B().get_a()) # this passes but for wrong reason 
     b_used = B().set_a('used') 
     b_unused = B() 

     print "b_used.get_a() should return ['initialized','used']" 
     print "b_unused.get_a() should return ['initialized']" 
     print "b_used.get_local() should equal b_unused.get_local() = 'OK'" 

     self.assertEqual(['initialized'], b_unused.get_a()) # >> fails with ['initialized'] =! ['initialized', 'used'] 
     self.assertNotEqual(b_unused.get_a(), b_used.get_a()) 


if __name__ == "__main__": 
    unittest.main() 

문제는 내가 그것을

+0

이 숙제인가 : 당신은 또한 당신의 단위 테스트를 수정해야

class A(object): __metaclass__ = ABCMeta def __init__(self): self._internal = ['initialized'] ... class B(A): def __init__(self): A.__init__(self) self.local = 'OK' ... 

? 그렇지 않은 경우 위에 설명한 것처럼 getter/setter 메서드를 사용하지 않는 것이 더 좋습니다. 파이썬에서는 추천하지 않습니다. – Daenyth

답변

1

당신은 인스턴스가 __init__() 속성을 초기화해야하며, 기본 클래스 __init__()B에서 전화 :

class TestCase(unittest.TestCase): 

    def test_implementation(self): 
     self.assertEqual(['initialized'], B().get_a()) # this passes but for wrong reason 
     b_used = B() 
     b_used.set_a('used') 
     b_unused = B() 
     ... 
+0

완벽하게 작동합니다. 방금 테스트에서 문제가 발생했습니다. 감사합니다. –

+0

super (B, self) .__ init __()이 아닌'A .__ init __ (self)'를 호출하는 특별한 이유가 있습니까? – user558061

+0

@ user558061 : 예, 있습니다. 'super()'는 기본 클래스 생성자를 호출하는 표준 방법으로 간주되어서는 안됩니다. 특정 설정에서만 제대로 작동합니다. –

0

인스턴스가 정의되어야한다 특성을 사전에

감사 클래스 B의 인스턴스 객체가 될 필요가 클래스 A의 obj 클래스 _internal 때문이다 방법, 예 : __init__, self에 설정하여.

관련 문제