2012-01-04 4 views
7

을 제공합니다 내가 가지고 다음과 같은 모델과 추상 기본 클래스장고 모델은 메타 클래스 충돌

import abc 
from django.db import models 


class AbstractBase(): 
    __metaclass__ = abc.ABCMeta 

    @abc.abstractmethod 
    def my_method(self): 
     return 


class MyModel(models.Model, AbstractBase): 
    @abc.abstractmethod 
    def my_method(self): 
     return 1 

그러나 나는 다음과 같은 오류를 얻고있다.

메타 클래스 충돌 : 파생 클래스의 메타 클래스는 모든 기지의 메타 클래스의 (비 엄격한) 서브 클래스해야합니다

나는 여기에 설명되어 여기에 문제가 (생각 http://code.activestate.com/recipes/204197-solving-the-metaclass-conflict/) 두 개의 기본 클래스에는 두 개의 다른 메타 클래스가 있으므로 파이썬은 자식 객체에 사용할 메타 클래스를 결정할 수 없습니다.

는이 문제를 해결하기 위해 나는 자식 클래스에게

abc.register(Child) 

를 등록하는 등록 방법에 따라 여러 상속 및 사용을 제거하지만 나는 원숭이 패치처럼 보이는 때문에이 방법처럼 정말하지 않았다.

이 문제를 해결할 다른 방법이 있습니까?

Model 메타 클래스를 명시 적으로 Child에 할당하려고 시도했지만 작동하지 않았습니다. 코드를 작성하여 문제를 해결할 방법을 찾고 있지 않습니다. 나는 이것이 나의 계급 구조를 변화시킴으로써 해결되어야한다고 생각한다.

+0

장고와 abc의 작업을 모두 수행하는 새 메타 클래스를 생성해야 할 것입니다. 아마 각각의 메타 클래스를 순서대로 호출하거나, 상속을 사용하여 호출 할 수 있습니다. – cha0site

+0

abs.register 메서드를 사용하는 것에 대해 아무런 해킹도 없습니다.이 경우 정확하게 설계되었습니다. BTW, 파이썬 방식으로 생각하는 일들이 이루어지기 때문에 인터페이스와 같은 것들을 거의 필요로하지 않습니다. 아마도 정적 언어로 작업하는 방식에 너무 제약을받을 것입니다. – jsbueno

+0

@jsbueno - 당신 말이 맞겠지 만 인터페이스 기능을 어떤 식 으로든 구현해야 할 것입니다. 다음은 이식의 예입니다 (https://gist.github.com/1559689). 파이썬에서이 기능을 구현하는 더 좋은 방법이 있습니까? – yilmazhuseyin

답변

2

제외하고 모두 ABCMetaModelBase, 에서 상속 새로운 메타 클래스를 만들거나 ModelBase에서 ABCMeta 상속을에서, 많은 당신이 할 수 없다.

그러나 다른 등록 패턴이 적절할 수 있습니까? 어쩌면 contrib.admin.autodiscover과 같은 것일 수 있습니까? 또는 클래스 데코레이터? 또는 적절한 클래스 (예 : for var in globals().values(): if isinstance(var, type) and issubclass(var, AbastractBase): register(var))에서 register을 호출하는 .py 파일 맨 아래의 루프?

: D' oh. 나는 ABCMeta이 예이고, ABCMeta이 아니라고 가정했다. 그게 너무 작은 잠에서 StackOverflow 브라우징에 대한거야.

+0

이것에 대한 나의 결론은 abc 's를 인터페이스로 사용하고 있다면 abc.register를 사용해야합니다. 정말 인터페이스 (http://www.python.org/dev/peps/pep-0245/)를 구현하는 더 좋은 방법이 있어야한다고 생각합니다. 그것들이 없으면 파이썬의 기능이 나에게 아주 약해 보입니다. – yilmazhuseyin

+3

"이것이 파이썬의 OO를 약하게 만든다"고 느끼면, "강력한 OO에 대한 요구 사항"에 대한 이해가 파이썬의 디자이너와 크게 다르다는 것을 겸손하게 제안 할 수도 있습니다. (또는 실수로 "oo"를 타이핑 할 때 "정적 유형 검사"?) –