2009-09-11 4 views
3

두 개의 클래스 X & Y가 있다고 가정합니다. 클래스에 속성을 추가하여 새로운 클래스 X1과 Y1을 생성함으로써 이러한 클래스를 꾸밀 수 있습니다. 예를 들어Python은 부모 객체 유형을 변경하기 위해 클래스를 장식합니다

:

class X1(X): 
    new_attribute = 'something' 

class Y1(Y): 
    new_attribute = 'something' 

new_attribute 항상 X1 및 Y1 모두 동일 할 것이다. X & Y는 다중 상속이 불가능하다는 점을 제외하고는 의미있는 방식으로 관련이 없습니다. 다른 속성들도 있습니다. 그러나 이것은 설명하기 위해 퇴화 된 것입니다.

내가 이것을과 복잡함을하고있어 같은 느낌,하지만 다소 likeso 데코레이터를 사용하는 생각했다 :

def _xywrap(cls): 
    class _xy(cls): 
    new_attribute = 'something' 
    return _xy 

@_xywrap(X) 
class X1(): 
    pass 

@_xywrap(Y) 
class Y1(): 
    pass 

나는 매우 일반적인 패턴이없는 것 같은이 느낌, 나는 많은 것 생각, 의견 및 피드백이 필요합니다.

읽어 주셔서 감사합니다.

브라이언

편집 : 예 : 여기

이 불 수있는 관련 추출물이다. 여기
from google.appengine.ext import db 

# I'm including PermittedUserProperty because it may have pertinent side-effects 
# (albeit unlikely), which is documented here: [How can you limit access to a 
# GAE instance to the current user][1]. 

class _AccessBase: 
    users_permitted = PermittedUserProperty() 
    owner = db.ReferenceProperty(User) 

class AccessModel(db.Model, _AccessBase): 
    pass 

class AccessExpando(db.Expando, _AccessBase): 
    pass 

# the order of _AccessBase/db.* doesn't seem to resolve the issue 
class AccessPolyModel(_AccessBase, polymodel.PolyModel): 
    pass 

가 하위 문서의 : 다음과 같이 일반적인 클래스는

class Thing(AccessExpando): 
    it = db.StringProperty() 

때때로 것은 다음과 같은 특성을 갖게됩니다

Thing { it: ... } 

그리고 다른 시간 :

Thing { it: ..., users_permitted:..., owner:... } 

나는 무섭다. 왜 Thing이 때때로 _AccessParent 속성을 갖고, 다른 때는 그렇지 않은지 파악해야합니다.

+0

클래스에 직접 정의 된 속성을 단순히 간단하게 정의하는 것이 나쁜 이유는 무엇입니까? (예 : 여러 속성이있는 경우 - 그러나 X/Y가 서로 관련이 없다고 말한 경우) 무엇이든지 상관없이 명시 적으로 정의해야하는 것처럼 보입니다. 수업. – Fragsworth

+0

@Fragsworth - 추가 할 속성이 많습니다. 실제로 X/Y 클래스가 5 개 이상 있습니다 (예를 들어 X & Y는 단지 축약 형입니다). 추가 할 속성은 항상 동일합니다. DRY를 위반하여 중복 속성의 일종의 리팩터링을 사용하지 않아 코드를 만듭니다. –

답변

5

사용 3 인수 type :

def makeSomeNicelyDecoratedSubclass(someclass): 
    return type('MyNiceName', (someclass,), {'new_attribute':'something'}) 

당신이 추측으로 이것은, 참으로, 합리적으로 인기 관용구.

편집 : someclass 당신이 추출하고 type 자체의 대신 (1 인수 type로)를 사용해야 할 수도 있습니다 메타 클래스 정의가있는 경우, 그것을 유지하기 위해 (이것은의 경우 될 수있는 일반적인 경우에 장고와 앱 엔진 모델) :

간단한 버전은 위 않는 곳도 작동
def makeSomeNicelyDecoratedSubclass(someclass): 
    mcl = type(someclass) 
    return mcl('MyNiceName', (someclass,), {'new_attribute':'something'}) 

(간단한 경우부터) 된 사용자 정의 메타 클래스/type(someclass) is typew

+0

안녕하세요 Alex! 답변을 업데이트 해 주셔서 감사합니다. 나는 어제 이것을 본 직후에 실제로 코멘트를 시작했지만, 응답하기 전에 그것을 시험 해보기 위해 기다리고있었습니다. mcl은 필자가 간략하게 고려한 요점이었다. 나는 이걸 시험해보고 이번 주 언젠가는 알려주지. 귀하의 의견과 의견을 많이 보내 주시면 감사하겠습니다. 이것은 흥미로운 문제입니다. :) –

2

multiple inheritance을 사용할 수없는 이유는 무엇입니까?

class Origin: 
    new_attribute = 'something' 

class X: 
    pass 

class Y: 
    pass 

class X1(Origin, X): 
    pass 

class Y1(Origin, Y): 
    pass 
+0

답장을 보내 주셔서 감사합니다. X & Y를 만들 때 리플렉션이 사용 중이므로 다중 상속이 작동하지 않습니다 (예 : X는 google.appengine.ext.db.Model, Y는 django.db.model, Z는 google.appengine.ext.db 임). .polymodel.Polymodel 등). 그렇기 때문에 질문에 다중 상속이 불가능하다는 것을 언급합니다. –

+0

... 또는 명확히하기 위해 ... 나는 그것이 가능하지 않다고 생각합니다. : o) 누군가가 그 사실을 보여줄 수 있다면 나는 기뻐할 것이다. –

+1

이 상황에서 다중 상속이 작동하지 않는 이유를 잘 모르겠다. 여기에있는 보이저의 예제에서 클래스 X1 (Origin, google.appengine.db.Model) 및 클래스 Y1 (Origin, django.db.Model)이 될 수 있습니다. 그렇습니까? –

3

voyager's answer에 귀하의 의견에 응답 :

from google.appengine.ext import db 

class Mixin(object): 
    """Mix in attributes shared by different types of models.""" 
    foo = 1 
    bar = 2 
    baz = 3 

class Person(db.Model, Mixin): 
    name = db.StringProperty() 

class Dinosaur(db.polymodel.PolyModel, Mixin): 
    height = db.IntegerProperty() 

p = Person(name='Buck Armstrong, Dinosaur Hunter') 
d = Dinosaur(height=5000) 

print p.name, p.foo, p.bar, p.baz 
print d.height, d.foo, d.bar, d.baz 

Buck Armstrong, Dinosaur Hunter 1 2 3 
5000 1 2 3 

의 결과가 마음에 없었 무엇인가요 것을 실행?

+0

이것은 작동합니다. 예를 들어 어떤 이유로 작동하지 않습니다 (예 : 단위 테스트 통과). Person 클래스 (Mixin, db.Model),하지만 그것을 반전했습니다 (Person 클래스 (db.Model, Mixin)) 이제 잘 작동합니다. 이것은 내가 예상하고 바라는 행동이므로, 귀하의 답변을 게시 해 주셔서 고맙습니다. 고맙습니다. –

+0

내가 틀 렸습니다. 이것은 가끔씩 만 작동합니다. 그것이 때때로 작동하고 다른 것들은 그렇지 않은 이유는 다른 사람들이 풀 수있는 수수께끼 일뿐입니다. 때때로 Mixin 속성을 가진 서브 클래스 (예 : Person)를 얻고 때로는 그것들없이 서브 클래스를 얻는다 고 말하면됩니다. 설명 할 수없는 것이 있다면 - 나는 더 많은 정보를 게시 할 것입니다. –

+0

이 동작을 나타내는 일부 코드를 표시 할 수 있습니까? 믹스 인의 프로퍼티가 다른 슈퍼 클래스의 프로퍼티를 섀도 잉 (또는 섀도 잉) 할 가능성이 있습니까? –

관련 문제