host_name, kernel_version, bios_version 등과 같은 컴퓨터에 대한 세부 정보를 검색하기위한 클래스를 만들고 있습니다. 일부 세부 정보는 다른 것보다 수집하는 데 더 많은 비용이 들기 때문에 get_ * 함수를 사용하여 검색하지만 개체가 필요할 경우 결과를 해당 캐시에 보관합니다. 나는 커널 버전은 그래서 검색 할 수 있도록 사전 객체처럼 보이게을 구현 고려하고 :고정 된 읽기 전용 필드에 대한 동적 특성 또는 사용자 지정 사전
system = System()
kver = system['kernel_version']
이 데이터를 검색하기 위해 내부적으로 인스턴스 방법 get_kernel_version(self)
를 호출합니다. 위의 인스턴스화 된 객체에서 두 번째로 커널 버전을 검색하면 원래 호출의 캐시 된 결과가 get_kernel_version(self)
으로 반환됩니다. 이러한 모든 키/값 쌍은 읽기 전용이며 사용 가능한 get_ * 메서드에 따라 고정 된 수가 있으며 나중에 추가 할 수있는 새 키가 없으므로 일반 사전과 같지 않습니다. values()
함수와 같은 함수를 호출 할 필요가 없어야합니다.이 함수는 모든 get_ * 함수가 불필요하게 히트되도록합니다. 또한 구문은 내가 원하는 것보다 좀 더 장황하다. 대신 system.kernel_version
을 사용하면이 사용 사례에 더 자연스럽게 보입니다.
더 나은 접근 방법이 클래스 인스턴스에 동적 속성을 사용할지 여부를 고려하고 있습니다. 그러나 모든 특성 목록을 검색하는 자연스러운 방법이 필요하지만이를 지원하는 내부 메서드는 필요하지 않습니다. 아마 __dir__
특수 메서드를 사용하여 keys()
사전 목록과 비슷한 목록을 반환 할 것입니다. 목록에서 kernel_version 및 host_name을보고 싶지만 __class__
또는 get_kernel_version
이 아닙니다. 이것은 __dir__
의 정의에 대한 권장 관행에 어긋나는 것 같습니다. 그래서 이것이 올바른 접근 방법인지 확실하지 않습니다.
적절한 속성이 이미 정의되어 있지 않은 경우 유일한 작업이 get_ * 함수를 사용하여 구체적인 클래스를 호출하는 프록시 클래스 인스턴스를 반환 할 수 있습니다. 여기
내가 사전 접근 방식을 구현하는 실험을하고있어 버전의 예입니다['host_name', 'kernel_version']
host_name: localhost
kernel_version: 4.7.0
"'System' object has no attribute 'get_bios'"
Read-only
은 위의 코드는 아직 캐싱을 구현하지 않습니다
class System(dict):
def __getitem__(self, key):
try:
return getattr(self, 'get_'+key)()
except AttributeError as ex:
raise KeyError(ex.message)
def __setitem__(self, key, value):
raise Exception('Read-only')
def __delitem__(self, key, value):
raise Exception('Read-only')
def keys(self):
return [ x[4:] for x in dir(self) if x.startswith('get_') ]
def get_host_name(self):
return 'localhost'
def get_kernel_version(self):
return '4.7.0'
system = System()
print repr(system.keys())
for key in system.keys():
print '{0}: {1}'.format(key, system[key])
try:
system['bios']
except Exception as ex:
print str(ex)
try:
system['kernel_version'] = '5.0'
except Exception as ex:
print str(ex)
다음과 같은 출력을 생성 어떤 값은 아직 있지만 추가하기 쉽습니다. 그러나, 나는 이것을 속성으로해야하는 것처럼 느껴진다. 나는 단지 내가 그렇게했을 때 나는
keys()
과 같은 기능을 에뮬레이트하기 위해
__dir__
을 남용해야하는지 확신 할 수 없다.
읽기 전용 사전을 에뮬레이션하거나 동적 속성이있는 클래스 인스턴스를 제공해야합니까?
당신은 당신을 허용 것이다 (https://code.activestate.com/recipes/576972-attrdict/)이 ['AttrDict' 레시피] 같은 것을 사용할 수 있습니다 필드에 접근하기 위해 도트 표기법을 사용하고 수정을 통해 읽기 전용으로 만드는 또 다른 접근법은 내용에 대한 액세스를 제어하기 위해'__getattr __() '을 사용하는 것입니다. 두 기술 모두 캐싱을 지원할 수도 있습니다. 편집] 귀하의 질문에 좀 더 구체적으로, 특히 샘플 코드를 추가하여, 나는 아마도 추가 세부 사항을 제공 할 수 있습니다. – martineau
@martineau 내가 뭘하는지에 대한 기본 아이디어의 예제를 추가했습니다 에 대한. – penguin359
코드를보고 좀 더 생각해 보면, 기본적으로 괜찮은 것 같아요. 당신이 가지고있는 keys() 메소드에 대한 데이터를 자동으로 생성하도록 향상시킬 수 있습니다. 아래 [내 대답] (http://stackoverflow.com/a/39171820/355230)을 참조하십시오. – martineau