2010-06-19 3 views
11

필자는 클래스 상속, 추상 기본 클래스 및 파이썬 인터페이스를 설명하는 설명서를 읽었습니다. 그러나 내가 원하는 것만으로 솔기가없는 것은 아닙니다. 즉, 가상 클래스를 작성하는 간단한 방법입니다. 가상 클래스가 호출되면, 매개 변수가 무엇인지를 기반으로 좀 더 구체적인 클래스를 인스턴스화하고 호출 함수를 다시 돌려 주길 원합니다. 지금은 가상 클래스에 대한 호출을 기본 클래스로 재 라우팅하는 요약 방법이 있습니다. 단이 기능은 전달받을()는 number_of_edges 호출로,가상 수업 : 제대로하고 있습니까?

class Shape: 
    def __init__(self, description): 
     if description == "It's flat": self.underlying_class = Line(description) 
     elif description == "It's spiky": self.underlying_class = Triangle(description) 
     elif description == "It's big": self.underlying_class = Rectangle(description) 
    def number_of_edges(self, parameters): 
     return self.underlying_class(parameters) 

class Line: 
    def __init__(self, description): 
     self.desc = description 
    def number_of_edges(self, parameters): 
     return 1 

class Triangle: 
    def __init__(self, description): 
     self.desc = description 
    def number_of_edges(self, parameters): 
     return 3 

class Rectangle: 
    def __init__(self, description): 
     self.desc = description 
    def number_of_edges(self, parameters): 
     return 4 

shape_dont_know_what_it_is = Shape("It's big") 
shape_dont_know_what_it_is.number_of_edges(parameters) 

내 재 라우팅 멀리 최적로부터 :

아이디어는 다음과 같다. 이런 모양을 Shape에 추가하면 속임수를 쓰지 않습니다.

def __getattr__(self, *args): 
    return underlying_class.__getattr__(*args) 

내가 뭘 잘못하고 있니? 전체 아이디어가 잘못 구현 되었습니까? 어떤 도움이라도 대단히 감사합니다.

def factory(description): 
    if description == "It's flat": return Line(description) 
    elif description == "It's spiky": return Triangle(description) 
    elif description == "It's big": return Rectangle(description) 

나 :

+0

'. 즉, 클래스는'object'의 서브 클래스 여야합니다. –

+0

당신이하려는 것은 "가상 클래스"가 아닌 가상 생성자를 가진 클래스라고도합니다.관련 질문보기 [_ 정확히 클래스 공장입니까?] (http://stackoverflow.com/questions/2526879/what-exactly-is-a-class-factory) – martineau

답변

14

나는 공장으로 그 일을 선호

def factory(description): 
    classDict = {"It's flat":Line("It's flat"), "It's spiky":Triangle("It's spiky"), "It's big":Rectangle("It's big")} 
    return classDict[description] 

및 모양

class Line(Shape): 
    def __init__(self, description): 
     self.desc = description 
    def number_of_edges(self, parameters): 
     return 1 
에서 클래스를 상속
+0

두 번째 팩토리 함수는 모든 유형의 객체를 구성합니다. 그 중 하나만 반환하더라도 호출 된 시간입니다. 'class_dict = { "flat": Line, ...} "다음에 return class_dict [description (description)'을 반환한다. –

0
당신은 object.__class__와 함께 클래스를 변경할 수 있습니다

, 그러나 임의의 클래스의 인스턴스를 반환하는 함수를 만드는 것이 훨씬 낫다.

class A(object): 
    pass 
1

파이썬 밖으로 가상 수업을하지 않습니다이 같은 파이썬 3 사용하여 사용하지 않는

다른 노트에

, 모든 클래스는, 그렇지 않으면 당신은 이전 스타일 클래스와 끝까지, object에서 상속해야 상자의. 직접 구현해야합니다 (가능한 것이 좋습니다, Python의 리플렉션 기능은이를 수행 할 수있을 정도로 강력해야합니다).

그러나 가상 클래스가 필요한 경우 베타, gBeta 또는 Newspeak와 같은 가상 클래스가있는 프로그래밍 언어를 사용하지 않는 것이 어떻습니까? (아직 다른 사람이 있습니까?)

그러나이 특별한 경우에는 가상 클래스가 솔루션을 단순화하는 방법을 실제로 알지 못합니다. 적어도 예제에서는 제공하지 않았습니다. 어쩌면 왜 가상 수업이 필요하다고 생각 하는지를 설명 할 수 있습니까?

내가 잘못 생각하지 말라. 나는 가상 클래스를 좋아하지만, 단지 3 개의 언어 만이 구현되었다는 사실은 그 중 3 개 중 하나만이 여전히 살아 있으며, 그 중 3 개 중 실제로 0 개가 실제로 사용된다는 것을 다소 말하고있다. & hellip;

+1

* BTW : 다른 것들이 있습니까? * : C++가 떠오릅니다. – user1717828

+0

흥미 롭습니다! 나는 그것을 몰랐다. C++에서 가상 클래스를 읽을 수있는 링크가 있습니까? Wikipedia에 따르면 C++에서 중첩 클래스는 그 클래스를 포함하는 정적 멤버입니다. 즉, 실제로는 * 참 * 중첩 클래스가 아닙니다 (둘러싸는 클래스의 둘러싸는 * 인스턴스 *의 멤버입니다). 그리고 가상 클래스가 실제 중첩 클래스 (즉, 다른 가상 멤버와 마찬가지로 하위 클래스에서 재정의되는 실제 중첩 클래스)의 특별한 경우라고 생각하면 C++에서 가상 클래스를 가질 수없는 것으로 보입니다. –

+0

Mmm, AFAIK C++ sort *는 가상 클래스가 무엇인지 정의합니다. 왜냐하면 언어가 너무 많이 사용되고 널리 사용되기 때문입니다. [가상/추상 클래스] (https://en.m.wikipedia.org/wiki/Virtual_method_table#Example)는 인스턴스화 될 수 없으며 상속 될 뿐이지 만 다른 클래스가 제공하는 템플릿과 더 비슷합니다. – user1717828

18

나는 TooAngel에 동의하지만, __new__ method을 사용합니다. 단지 새로운 스타일의 클래스에 대한 작동 __getattr__`

class Shape(object): 
    def __new__(cls, *args, **kwargs): 
     if cls is Shape:       # <-- required because Line's 
      description, args = args[0], args[1:] #  __new__ method is the 
      if description == "It's flat":   #  same as Shape's 
       new_cls = Line 
      else: 
       raise ValueError("Invalid description: {}.".format(description)) 
     else: 
      new_cls = cls 
     return super(Shape, cls).__new__(new_cls, *args, **kwargs) 

    def number_of_edges(self): 
     return "A shape can have many edges…" 

class Line(Shape): 
    def number_of_edges(self): 
     return 1 

class SomeShape(Shape): 
    pass 

>>> l1 = Shape("It's flat") 
>>> l1.number_of_edges() 
1 
>>> l2 = Line() 
>>> l2.number_of_edges() 
1 
>>> u = SomeShape() 
>>> u.number_of_edges() 
'A shape can have many edges…' 
>>> s = Shape("Hexagon") 
ValueError: Invalid description: Hexagon. 
+1

nice - 나도 그런 식으로 생각했지만 파이썬 구문을 모른다. – TooAngel

+0

이 예제에서 Shape는 _metaclass_로 알려져있다. –

+2

@Daniel : 나는 그렇게 생각하지 않는다. 메타 클래스는 대개 수업이 작동하는 방식을 변경합니다. Objective-C에서 이것은 * Class Cluster *라고 불릴 것입니다. 파이썬에서 적절한 이름이 무엇인지 모르겠습니다. –