2016-09-11 2 views
2

내가 기다릴 수있는 미래를 반환하는 디스크립터를 쓸 수있다.python3.5에서 비동기 적으로 디스크립터를 설정하기

class AsyncDescriptor: 
    def __get__(self, obj, cls=None): 
     # generate some async future here 
     return future 

    def __set__(self, obj, value): 
     # generate some async future here 
     return future 

class Device: 
    attr=AsyncDescriptor() 

device=Device() 

이제 coroutine의 값을 value=await device.attr으로 얻을 수 있습니다.

이 속성은 어떻게 설정합니까?

  • await device.attr=5 -> 구문 에러 : 표현을 기다리고 할당 할 수 없습니다
  • await setattr(device, 'attr', 5) -> 형식 오류 : 개체 NoneType 표현 '기다리고'에서 사용할 수 없습니다
  • device.attr=5 -> RuntimeWarning : 코 루틴 '__set__' 결코 기다려지지 않았습니다.
+0

'__set__'은 (는) 아무 것도 반환하지 않아야합니다. 'value'를 비동기식으로 해결하고 싶습니까? – jonrsharpe

+0

예, 이것이 목표가 될 것입니다. –

+0

그러나 예는 모두 미래가 아니라 가치를 전달하고 있습니다. – jonrsharpe

답변

2

당신이하려는 것은 불가능합니다 (파이썬 3.5 포함).

__get__이 미래를 반환하는 것이 현명하지만 __set__ 비동기는 Python 3.5에서 지원되지 않습니다. __set__의 반환 값은 할당의 "반환 값"이 없으므로 Python에서 무시됩니다. 그리고 __set__에 대한 호출은 항상 동기식입니다. a = (b.c = 5)과 같은 것은 이미 눈치 채신 것처럼 실제로 SyntaxError을 발생시킵니다.

await device.attr = 5 같은 비동기 할당이 허용된다면, 아마 코 루틴 __aget__async for/__aiter__ 비동기 컨텍스트 관리자 (async with/__aenter__) 및 비동기 반복 (유사하게 __aset__ 같은 특별한 방법으로 즉, 비동기 기술자에 대한 별도의 프로토콜이있을 것). async/await 지원의 설계 결정은 PEP 492을 참조하십시오.

__get__ 미래를 반환해도 __get__이 코 루틴이되지 않습니다.

추가 컨텍스트가 없으면 명시 적으로 더 잘 수행되어야하는 설명자 프로토콜에 의해 제공된 속성 액세스 추상화 뒤에 숨기고 싶은 것처럼 보입니다.하지만 그건 당연한 것입니다.

관련 문제