뭔가. 진짜 질문은 당신이 이것을하고 싶어하는 이유입니다. 나는 이것이 교육만을위한 것이라고 가정 할 것입니다. 실제로, 이것이 사용될 수있는 것이 무엇이든 명시 적으로 (즉, 메타 클래스를 사용하지 않고 @classmethod
을 추가하는 것보다) 더 잘 수행 될 수 있습니다.
두 가지 옵션을 알고 있습니다. 클래스 정의를위한 맞춤 네임 스페이스 및 후 처리가 __new__
입니다. 첫 번째 메소드는 매우 차갑고 어떤 경우에는 (예 : 메소드 정의의 순서를 기억하는 등) 피할 수 없지만, 후자는 더 간단하고 유연하며 실수로 여러 개의 할당을 동일한 이름으로 나눌 수없고 Python 2에서 사용할 수 있습니다. 당신의 목적은이 전 배제,하지만 난 이 사용 파이썬 3
사용자 정의 네임 스페이스를, 당신은 메타 클래스에서 __prepare__
를 정의하고 돌아왔다 공급하기 위해 할 수있는 모든 사용자를 위해 그것을에서 떠날거야 사전 같은 객체 (Ferdinand Beyer는 주석에 언급 : collections
에 정의 된대로 매핑 인터페이스가 충분 함). 이 경우 값이 callable
인지 확인하려면 사전에 __setitem__
을 무시하고, 그렇다면 에 저장하십시오. 아래 코멘트에 많은 것을 썼습니다. 아래 코드를 대폭 개선했습니다. Ferdinand Beyer는 callable(classmethod(...))
이 거짓임을 알았고 agf는 @classmethod
과 Python 3 호환성과의 불일치를 지적했습니다.
import types
# Either this, in a dictionary class instanciated in __prepare__
# Again, Python 3 only
def __setitem__(self, name, value):
if isinstance(value, types.FunctionType):
value = classmethod(value)
super().__setitem__(name, value)
# __prepare__ would be: return AutomaticClassMethodNamespace() or something
# Or this in the metaclass
def __new__(mcls, clsname, bases, ns):
for name, value in ns.items():
if isinstance(value, types.FunctionType):
ns[name] = classmethod(value)
# Any other metaclass behaviour
함수를 검사하는 표준 방법은 if isinstance (v, types.FunctionType) :'입니다. 'm','k','v'보다 더 의미있는 이름을 사용하면 더 좋을 것입니다. – agf
@agf : 나는 주문을 믿지 않는다. – georg
나는 그 의견이 무엇을 의미하는지 생각하지 못합니다. 메타 클래스 함수의 이름을 변경한다고 가정합니다. 코드가 깨집니다. 함수 대신에'type'을 상속받은 클래스를 사용한다고 가정합니다. 코드가 깨집니다. 그래서 간접적으로 찾는 것이 아니라 실제 유형을 사용하는 것입니다. 특히 누군가에게 설명 할 때 의미있는 이름을 사용하는 것이 기본적인 상식입니다. – agf