2013-01-04 2 views
0

내 클래스의 생성자에서 속성을 선언하고 싶습니다.Python : 항목 목록에서 생성자의 속성 정의

MaterialOne 클래스는 내가 현재 가지고있는 것을 보여줍니다. 모든 속성은 별도로 정의해야합니다. 그러나 비슷한 속성의 그룹을 갖게됩니다. 동일한 fset/fget/fdel을 제공하고 싶습니다.

모든 속성을 명시 적으로 작성해야하기 때문에보다 간결한 방식으로 속성을 정의하고 싶습니다. 그래서 나는 생성자가 이것을 처리하도록 생각했다. 클래스 MateralTwo 내가 어떻게 염두에두고 보여줍니다. 내가 TypeErrors를 얻을로

불행히도 그것은 작동하지 않습니다

TypeError: get_property() takes exactly 1 argument (2 given) 

는 불평 왜 이해할 수있다,하지만 난 어떤 솔루션을 생각할 수 없다. 필자는 반드시 생성자의 목록에서 속성을 정의하고 싶지 않습니다. 내가 찾고있는 것은 그것들을 정의하는보다 간결하고 깨끗한 방법이다.

class MaterialOne(object): 
    def __init__(self): 
     pass; 

    def del_property(attr): 
     """Abstract deller""" 
     def del_attr(self): 
      setattr(self, attr, None); 
     return del_attr 

    def set_property(attr): 
     """Abstract setter.""" 
     def set_attr(self, x): 
      setattr(self, attr, x);    
     return set_attr 

    def get_property(attr): 
     """Abstract getter""" 
     def get_attr(self): 
      if getattr(self, attr) is not None: 
       return getattr(self, attr); 
      else: 
       return 'Some calculated value..' 
     return get_attr 

    _young = None; 
    _shear = None; 
    _poisson = None; 

    young = property(fget=get_property('_young'), fset=set_property('_young'), fdel=del_property('_young')); 
    shear = property(fget=get_property('_shear'), fset=set_property('_shear'), fdel=del_property('_shear')); 
    poisson = property(fget=get_property('_poisson'), fset=set_property('_poisson'), fdel=del_property('_poisson')); 


class MaterialTwo(object): 
    def __init__(self): 
     properties = ['young', 'shear', 'poisson']; 
     self.create_properties(properties) 

    def del_property(attr): 
     """Abstract deller""" 
     def del_attr(self): 
      setattr(self, attr, None); 
     return del_attr 

    def set_property(attr): 
     """Abstract setter.""" 
     def set_attr(self, x): 
      setattr(self, attr, x);    
     return set_attr 

    def get_property(attr): 
     """Abstract getter""" 
     def get_attr(self): 
      if getattr(self, attr) is not None: 
       return getattr(self, attr); 
      else: 
       return 'Some calculated value..' 
     return get_attr   

    def create_properties(self, items): 
     for item in items: 
      storage = '_'+item; 
      setattr(self, storage, None); 
      setattr(self, item, property(fget=self.get_property(storage), fset=self.set_property(storage), fdel=self.del_property(storage))); 


steel = MaterialOne(); 
steel.young = 2e11; 
steel.poisson = 0.3; 
print steel.poisson 
print steel.shear 

carbon = MaterialTwo(); 
carbon.young = 2e11; 
carbon.poisson = 0.3; 
print carbon.poisson 
print carbon.shear 

코드에 대해 더 자세히 설명합니다. 제가 쓰고 싶은 것은 재료, 고체, 액체, 기체를위한 클래스입니다. 그것들 각각은 재료의 하위 클래스입니다. 많은 물성치가 할당됩니다. 어떤 것은 정의 된 것을 토대로 계산 될 수 있습니다. 2 개의 탄성 계수가 주어지면 예를 들어 3 분의 1을 계산할 수 있습니다.

저는 MaterialOne과 아주 비슷한 것을 사용하여 구현했습니다. 그러나 더 많은 물성치를 얻고 있으며 이러한 종류의 계산을 더 많이 포함 할 것이므로보다 체계적이고 체계적인 정리를하고 싶습니다. 내가 MaterialTwo에서했던 것처럼 그것을 쓰는 것은 나에게 가능성이다.

+2

귀하의 문제와 관련없는 스타일 포인트 : 파이썬에서 세미콜론이 필요하지 않습니다 – Will

+0

궁극적으로 당신은 무엇을 성취하려고합니까? (잘못된 경로로 향하고있는 것처럼 보입니다.) 속성에 처음 액세스 한 다음 값을 캐시하면 "요청시"각 값을 계산하려고합니까? –

답변

1
setattr(self, item, property(... 

이 궁극적으로 문제입니다. 속성은 설명자이므로 인스턴스가 아닌 클래스에 바인딩되어야합니다. override __getattr__(), __setattr__(), and __delattr__()이 필요하고 거기서 구현하십시오.

+0

정확히, 그것은 그 라인에옵니다. 그리고 당신이 말했듯이, 설명자는 클래스가 아니라 인스턴스에 바인딩됩니다. 따라서 생성자에서 작동하지 않습니다. 지금은 이해. 재정의가 포함되는 것을 보게 될 것이지만, MaterialOne에서 어떻게 수행했는지 되돌아 가야 할 것 같습니다. – FRidh

0

모든 정의는 첫 번째 인수로 self이어야합니다.

는 이러한 기능이 있어야 할 방법입니다 방법은 파이썬의 객체라고

def del_property(self, attr): 
def sel_property(self, attr): 
def get_property(self, attr): 
-1

, 객체는 자동으로 당신을 말하는 오류를 얻고있는 이유는 첫 번째 인수로 전달된다 너무 많은 논쟁을 벌이고있다. 다른 사람들이 말했듯이, 함수에 대한 첫 번째 매개 변수로 self를 포함해야합니다.

관련 문제