문제

두 가지 클래스 X & Y가 있다고 가정 해 봅시다. 새로운 클래스 X1 및 Y1을 생성하기 위해 클래스에 속성을 추가하여 해당 클래스를 장식하려고합니다.

예를 들어:

class X1(X):
  new_attribute = 'something'

class Y1(Y):
  new_attribute = 'something'

new_attribute X1과 Y1 모두에 대해 항상 동일합니다. X & Y는 다중 상속 재산이 불가능하다는 점을 제외하고는 의미있는 방식으로 관련이 없습니다. 다른 속성 세트도 있습니다. 그러나 이것은 설명하기 위해 퇴화됩니다.

나는 이것을 과도하게 복잡하게 생각하지만, 나는 데코레이터를 사용한다고 생각했다.

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:... }

나는 왜 물건이 때때로 _accessparent 속성을 가지고 있는지, 그리고 다른 시간에 그렇지 않은지 알아낼 수 없었습니다.

도움이 되었습니까?

해결책

3 학습을 사용하십시오 유형:

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

이것은 실제로, 당신이 추측 한 것처럼, 합리적으로 인기있는 관용구입니다.

편집하다: 일반적인 경우 SomeClass가 사용자 정의 메타 클래스가있는 경우 추출 및 사용해야 할 수도 있습니다 (1- 연기와 함께 type) 대신 type 그 자체로, 그것을 보존하기 위해 (이것은 당신의 django 및 앱 엔진 모델의 경우 일 수 있음) :

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

이것은 위의 간단한 버전이 수행하는 곳에서도 작동합니다 (간단한 경우에는 사용자 정의 메타 클래스가 없기 때문입니다. type(someclass) is type).

다른 팁

귀하의 의견에 응답합니다 보이저의 대답:

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

그게 당신이 생각했던 것이 아닌가?

왜 사용할 수 없어요 다중 상속?

class Origin:
  new_attribute = 'something'

class X:
  pass

class Y:
  pass

class X1(Origin, X):
  pass

class Y1(Origin, Y):
  pass
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top