Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在python3.5中异步设置描述符_Python_Python 3.5_Python Asyncio_Descriptor - Fatal编程技术网

在python3.5中异步设置描述符

在python3.5中异步设置描述符,python,python-3.5,python-asyncio,descriptor,Python,Python 3.5,Python Asyncio,Descriptor,我可以写一个描述符,返回一个可以期待的未来 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 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()
现在,我可以在与
value=wait device.attr
的协同程序中获取值

如何设置此属性

  • 等待设备。attr=5
    ->语法错误:无法分配给等待表达式
  • await setattr(设备'attr',5)
    ->TypeError:object NoneType不能在'await'表达式中使用
  • device.attr=5
    ->运行时警告:从未等待协同路由“\uuuu set\uuuu”

您试图做的是不可能的(使用Python 3.5)

虽然
\uuuuu get\uuuuu
返回未来可能是明智的,但Python 3.5根本不支持将
\uuuuuu set\uuuuuuuu
异步。Python忽略了
\uuuuu set\uuuuu
的返回值,因为没有赋值的“返回值”。对
\uuuu set\uuuu
的调用始终是同步的。像
a=(b.c=5)
这样的东西实际上会引发一个
SyntaxError

如果允许像
wait device.attr=5
这样的异步分配,则可能会有一个单独的异步描述符协议,即使用协程
\uuuu aget\uuu
\uu aset\uuuu
作为特殊方法,类似于异步上下文管理器(
/
\uu aenter\uuu
异步)和异步迭代(
async for
/
\uuu aiter\uuuu
)。有关
async
/
wait
支持背后的设计决策,请参阅

还请注意,
\uuuuuuu获取
返回未来不会使
\uuuuu获取
成为一个协同程序


如果没有进一步的上下文,看起来您想在描述符协议提供的属性访问抽象背后隐藏一些东西,最好是显式地完成,但这当然取决于您。

您试图做的事情是不可能的(使用Python 3.5)

虽然
\uuuu get\uuuu
返回一个未来可能是明智的,但是Python 3.5不支持将
\uuu set\uuuuuu
异步。Python忽略了
\uu set\uuuuuu
的返回值,因为没有赋值的“返回值”。对
\uu set\uuuuuu
的调用总是同步的。类似于
a=(b.c=5)
实际上引发了一个
SyntaxError
,正如您已经注意到的那样

如果允许像
wait device.attr=5
这样的异步分配,则可能会有一个单独的异步描述符协议,即使用协程
\uuuu aget\uuu
\uu aset\uuuu
作为特殊方法,类似于异步上下文管理器(
/
\uu aenter\uuu
异步)和异步迭代(
async for
/
\uuu aiter\uuuu
)。有关
async
/
wait
支持背后的设计决策,请参阅

还请注意,
\uuuuuuu获取
返回未来不会使
\uuuuu获取
成为一个协同程序


如果没有进一步的上下文,看起来您想在描述符协议提供的属性访问抽象背后隐藏一些东西,最好是显式地完成,但这当然取决于您。

但是python非常好,如果您想编写device.attr=5,但等待设置 操作时,您只需借助上下文块即可(我不认为这是一个好主意,尽管它在无线程python场景中可能很有用):

import asyncio, sys

async def main():

    obj.attr = "not async value"
    print(obj.attr)

    print()
    print("now set with an async value")

    async with aio(obj):
        # ============== yes i can, thanks python ! ===
        obj.attr = 5
        # =============================================

    print(obj.attr)

    print("bye")
    flush_io()

def flush_io():
    sys.stdout.flush()
    sys.stderr.flush()

class attr:
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, objtype):
        if obj is None:
            print("__get__", obj, objtype)
            return self
        print("get", obj, objtype)
        return self.value

    def __set__(self, obj, value):
        if value is not obj.__class__:
            if obj in aio.updating:
                aio.setlist.append([self, value])
                print("    future set", self, value)
                return

            self.value = value
            print("set", obj, value)
            return
        print("__set__", obj, value)

    async def setter(self, value):
        print("    async updating", self, end=" ")
        for i in range(value):
            await asyncio.sleep(1)
            print(".", end="")
            flush_io()
        print()
        self.value = value

    def __repr__(self):
        return "<async attr>"

class aobj:

    attr = attr("empty")

    def __repr__(self):
        return "<aobj>"

class aio:
    updating = []
    setlist = []

    def __call__(self, obj):
        self.updating.append(obj)
        return self

    async def __aenter__(self):
        print("aenter", self.updating)

    async def __aexit__(self, *tb):
        self.updating.pop()
        while len(self.setlist):
            obj, value = self.setlist.pop()
            await obj.setter(value)
        print("aexit")


aio = aio()
obj = aobj()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
导入异步IO,系统
异步def main():
obj.attr=“非异步值”
打印(对象属性)
打印()
打印(“现在设置为异步值”)
与aio(obj)异步:
#===============是的,我能,谢谢你===
obj.attr=5
# =============================================
打印(对象属性)
打印(“再见”)
刷新_io()
def flush_io():
sys.stdout.flush()
sys.stderr.flush()
类别属性:
定义初始值(自身,值):
自我价值=价值
定义获取(self、obj、objtype):
如果obj为无:
打印(“\uuuu get\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
回归自我
打印(“获取”、对象、对象类型)
回归自我价值
定义设置(自身、对象、值):
如果值不是对象。\uuuu类\uuuuj:
如果目标在aio.update中:
aio.setlist.append([self,value])
打印(“未来设置”、自身、值)
返回
自我价值=价值
打印(“设置”、对象、值)
返回
打印(“\uuuuuuuuuuuuuuuuuuuuuu”,对象,值)
异步def设置器(自身,值):
打印(“异步更新”,self,end=”“)
对于范围内的i(值):
等待asyncio.sleep(1)
打印(“.”,end=“”)
刷新_io()
打印()
自我价值=价值
定义报告(自我):
返回“”
aobj类:
attr=attr(“空”)
定义报告(自我):
返回“”
aio类:
更新=[]
集合列表=[]
定义呼叫(自我,obj):
self.updateing.append(obj)
回归自我
异步定义(自):
打印(“aenter”,自我更新)
异步定义aexit(self,*tb):
self.updateing.pop()
而len(self.setlist):
obj,value=self.setlist.pop()
等待对象设置器(值)
打印(“aexit”)
aio=aio()
obj=aobj()
loop=asyncio.get\u event\u loop()
循环。运行\u直到完成(main())

但是python非常棒,所以如果您想编写device.attr=5,但等待设置 操作时,您只需借助上下文块即可(我不认为这是一个好主意,尽管它在无线程python场景中可能很有用):

import asyncio, sys

async def main():

    obj.attr = "not async value"
    print(obj.attr)

    print()
    print("now set with an async value")

    async with aio(obj):
        # ============== yes i can, thanks python ! ===
        obj.attr = 5
        # =============================================

    print(obj.attr)

    print("bye")
    flush_io()

def flush_io():
    sys.stdout.flush()
    sys.stderr.flush()

class attr:
    def __init__(self, value):
        self.value = value

    def __get__(self, obj, objtype):
        if obj is None:
            print("__get__", obj, objtype)
            return self
        print("get", obj, objtype)
        return self.value

    def __set__(self, obj, value):
        if value is not obj.__class__:
            if obj in aio.updating:
                aio.setlist.append([self, value])
                print("    future set", self, value)
                return

            self.value = value
            print("set", obj, value)
            return
        print("__set__", obj, value)

    async def setter(self, value):
        print("    async updating", self, end=" ")
        for i in range(value):
            await asyncio.sleep(1)
            print(".", end="")
            flush_io()
        print()
        self.value = value

    def __repr__(self):
        return "<async attr>"

class aobj:

    attr = attr("empty")

    def __repr__(self):
        return "<aobj>"

class aio:
    updating = []
    setlist = []

    def __call__(self, obj):
        self.updating.append(obj)
        return self

    async def __aenter__(self):
        print("aenter", self.updating)

    async def __aexit__(self, *tb):
        self.updating.pop()
        while len(self.setlist):
            obj, value = self.setlist.pop()
            await obj.setter(value)
        print("aexit")


aio = aio()
obj = aobj()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
导入异步IO,系统
异步def main():
obj.attr=“非异步值”
打印(对象属性)
打印()
打印(“现在设置为异步值”)
与aio(obj)异步:
#===============是的,我能,谢谢你===
obj.attr=5
# =============================================
打印(对象属性)
打印(“再见”)
刷新_io()
def flush_io():
sys.stdout.flush()
sys.stderr.flush()
C