필자가 작성한 코드에서 파이썬 설명자 프로토콜을 더 광범위하게 사용하기 시작했습니다. 일반적으로 기본 파이썬 조회 마술은 내가 원하는 일이지만 때로는 그 대신 __get__
메서드의 결과 대신 설명자 개체 자체를 가져 오려고합니다. 설명자의 유형을 알고 싶거나 설명자에 저장된 상태에 액세스하고 싶거나 몇 가지 일이 있습니다.설명자 마술없이 파이썬 속성 조회?
올바른 순서가 있다고 믿는 네임 스페이스를 탐색하고 설명자인지 여부에 관계없이 원시 특성을 반환하도록 아래 코드를 작성했습니다. 나는 표준 라이브러리에서 내장 함수 나 무언가를 찾을 수는 없지만 놀랍다. 나는 거기에 있어야한다는 것을 알았고, 나는 그것을 알아 채지 못했거나 올바른 검색 용어로봤을 뿐이다.
이미 파이어 폭스 배포판에 이미 이와 비슷한 기능이 있습니까?
감사합니다.
from inspect import isdatadescriptor
def namespaces(obj):
obj_dict = None
if hasattr(obj, '__dict__'):
obj_dict = object.__getattribute__(obj, '__dict__')
obj_class = type(obj)
return obj_dict, [t.__dict__ for t in obj_class.__mro__]
def getattr_raw(obj, name):
# get an attribute in the same resolution order one would normally,
# but do not call __get__ on the attribute even if it has one
obj_dict, class_dicts = namespaces(obj)
# look for a data descriptor in class hierarchy; it takes priority over
# the obj's dict if it exists
for d in class_dicts:
if name in d and isdatadescriptor(d[name]):
return d[name]
# look for the attribute in the object's dictionary
if obj_dict and name in obj_dict:
return obj_dict[name]
# look for the attribute anywhere in the class hierarchy
for d in class_dicts:
if name in d:
return d[name]
raise AttributeError
편집 10월 28일 (수),
데니스의 대답 2009 년은 나에게 기술자가 자신을 개체를 얻을 내 기술자 클래스에서 사용하는 규칙을했다. 그러나, 나는 기술자 클래스의 전체 클래스 계층 구조를 가지고 있었고, 내가
def __get__(self, instance, instance_type):
if instance is None:
return self
...
이러한 문제가 발생하지 않도록하려면 보일러와 마다__get__
기능을 시작하고 싶지 않았다, 나는 기술자 클래스 트리의 루트에서 상속 만든 다음과 같습니다 :
def decorate_get(original_get):
def decorated_get(self, instance, instance_type):
if instance is None:
return self
return original_get(self, instance, instance_type)
return decorated_get
class InstanceOnlyDescriptor(object):
"""All __get__ functions are automatically wrapped with a decorator which
causes them to only be applied to instances. If __get__ is called on a
class, the decorator returns the descriptor itself, and the decorated
__get__ is not called.
"""
class __metaclass__(type):
def __new__(cls, name, bases, attrs):
if '__get__' in attrs:
attrs['__get__'] = decorate_get(attrs['__get__'])
return type.__new__(cls, name, bases, attrs)
때로는 설명자 개체를 원하십니까? 이것은 기술자에 대한 핵심 기대 사항을 위반합니다. 속성과 같아 져야합니다. 그 근본적인 기대를 깨뜨리는 이유는 무엇입니까? 왜 그럴까요? 왜 그렇게 복잡한 것을 만드 는가? –
내가하고있는 일은 나에게 복잡해 보이지 않지만 디자인을 실험하고 있다고 말할 수있을 것 같다. 현재 나의 특별한 경우에는 게임에서 무기의 강도를 반환하는 설명자가 있습니다. 이 값은 기술자의 상태 (무기의 강도)와 인스턴스 (우주의 건강)의 함수입니다. 무기 종류는 다양합니다. 일반적으로 저는 값의 결과를 원하지만, 어떤 경우에는 어떤 종류의 무기인지, 즉 기술자의 유형을 알아야합니다. 설명자에 설명자 프로토콜의 일부가 아닌 메서드가 있고이를 호출하고 싶다면 어떻게해야합니까? –