小编Sah*_*and的帖子

在Python中,为什么lambda表达式可以引用正在定义的变量而不是列表?

这比任何事情都更具好奇心,但我注意到以下内容.如果我定义一个自引用的lambda,我可以轻松地做到:

>>> f = lambda: f
>>> f() is f
True
Run Code Online (Sandbox Code Playgroud)

但是,如果我要定义一个自引用列表,我必须在多个语句中执行:

>>> a = [a]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> a = []
>>> a.append(a)
>>> a[0] is a
True
>>> a
[[...]]
Run Code Online (Sandbox Code Playgroud)

我也注意到这不仅限于列表,但似乎除了lambda之外的任何其他表达式都不能引用赋值左边的变量.例如,如果您有一个带有一个节点的循环链表,那么您不能简单地去:

>>> class Node(object):
...     def __init__(self, next_node):
...         self.next = next_node
... 
>>> n = Node(n)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'n' is not …
Run Code Online (Sandbox Code Playgroud)

python

29
推荐指数
3
解决办法
3372
查看次数

上下文管理器和多处理池

假设您正在使用multiprocessing.Pool对象,并且您正在使用initializer构造函数的设置来传递初始化函数,然后在全局命名空间中创建资源.假设资源有一个上下文管理器.您将如何处理上下文管理资源的生命周期,前提是它必须贯穿整个过程的生命周期,但最终应该进行适当的清理?

到目前为止,我有点像这样:

resource_cm = None
resource = None


def _worker_init(args):
    global resource
    resource_cm = open_resource(args)
    resource = resource_cm.__enter__()
Run Code Online (Sandbox Code Playgroud)

从此处开始,池进程可以使用该资源.到现在为止还挺好.但处理清理有点棘手,因为multiprocessing.Pool类没有提供destructordeinitializer参数.

我的一个想法是使用该atexit模块,并在初始化程序中注册清理.像这样的东西:

def _worker_init(args):
    global resource
    resource_cm = open_resource(args)
    resource = resource_cm.__enter__()

    def _clean_up():
        resource_cm.__exit__()

    import atexit
    atexit.register(_clean_up)
Run Code Online (Sandbox Code Playgroud)

这是一个好方法吗?有更简单的方法吗?

编辑:atexit似乎没有工作.至少不是我上面使用它的方式,所以到目前为止我还没有解决这个问题的方法.

python multiprocessing contextmanager

20
推荐指数
1
解决办法
5123
查看次数

在另一个上下文管理器中处理上下文管理器的实例

如何在Python中处理在另一个上下文管理器中创建的上下文管理器?

示例:假设您具有A充当上下文管理器的类B,以及充当上下文管理器的类.但是类B实例必须实例化并使用类的实例A.我已经通过了PEP 343,这是我想到的解决方案:

class A(object):
    def __enter__(self):
        # Acquire some resources here
        return self

    def __exit__(seplf, exception_type, exception, traceback):
        # Release the resources and clean up
        pass


class B(object):
    def __init__(self):
        self.a = A()

    def __enter__(self):
        # Acquire some resources, but also need to "start" our instance of A
        self.a.__enter__()
        return self

    def __exit__(self, exception_type, exception, traceback):
        # Release the resources, and make our instance of A clean up as well
        self.a.__exit__(exception_type, …
Run Code Online (Sandbox Code Playgroud)

python contextmanager

15
推荐指数
2
解决办法
2699
查看次数

是否可以默认使git clone递归?

是否有可能默认git clonegit clone --recursive

git

14
推荐指数
1
解决办法
1549
查看次数

在Python生成器中是否有类似"self"的东西?

有没有办法在生成器的定义中获取对返回的生成器对象的引用?这类似于self传递给__next__迭代器方法内部方法的参数.浏览Python的文档后,我没有找到类似的东西.

这个问题出现的时候,我正在探索以下论文的大部分内容,我可以使用生成器作为协同程序在Python中实现.论文:http://citeseerx.ist.psu.edu/viewdoc/summary?doi = 10.1.1.19.79

我能做的最接近的是使用装饰器,它建立在David Beazley的coroutine装饰上,但感觉有点像黑客.

from functools import wraps


def coroutine(func):
    @wraps(func)
    def decorated(*args, **kwargs):
        f = func(*args, **kwargs)
        next(f)
        f.send(f)
        return f
    return decorated


@coroutine
def A():
    self = yield
    # do stuff...
Run Code Online (Sandbox Code Playgroud)

编辑:基于下面的答案,下面的类可以用作装饰器,让生成器接收self作为其第一个参数的引用.它具有额外的好处,任何用它装饰的发电机都具有这种类型coroutine.

class coroutine(object):
    """Decorator class for coroutines with a self parameter."""
    def __new__(cls, func):
        @wraps(func)
        def decorated(*args, **kwargs):
            o = object.__new__(cls)
            o.__init__(func, args, kwargs)
            return o
        return decorated

    def __init__(self, generator, args, …
Run Code Online (Sandbox Code Playgroud)

python coroutine

11
推荐指数
1
解决办法
713
查看次数

JavaScript中的比较运算符是否存在类型安全的等价物?

我刚刚在node.js控制台中尝试了以下内容:

> 5 <= "5"
true
Run Code Online (Sandbox Code Playgroud)

这意味着被处理的=部分<=是相同==的,而不是===.这使我立即尝试<==希望它会做你希望它会做的事情.但它不存在.

然后我尝试了以下内容:

> 5 < "6"
true
Run Code Online (Sandbox Code Playgroud)

然后我开始观察甚至更奇怪的行为:

> 5 < [6]
true
Run Code Online (Sandbox Code Playgroud)

这带来了一个更重要的问题:有没有类型安全的等价物<,>,<=,和>=

javascript

6
推荐指数
1
解决办法
304
查看次数

在Python中,有没有办法测试生成器对象以找出创建它的生成器?

给定一个生成器对象,是否可以测试它是否是由给定的生成器创建的?也许更好的说法,是否有可能测试我们的发电机的"类型"?由于生成器对象具有类型generator,因此使用typeisinstance不执行测试.

请考虑以下代码:

>>> def gen1():
...     yield 1
... 
>>> def gen2():
...     yield 2
... 
>>> g1 = gen1()
>>> g2 = gen2()
>>> 
>>> def do_something(f):
...     # need to know if f is a gen1 generator or a gen2 generator here
...     # isinstance(f, gen1)  raises a TypeError since gen1 is not a type
...     # type(f) is gen1 returns false
...     print(f)
... 
>>> do_something(g1)
<generator object gen1 at 0x100dcb370> …
Run Code Online (Sandbox Code Playgroud)

python

4
推荐指数
1
解决办法
116
查看次数

为什么Python的生成器不是类型?

问题的简短版本:为什么生成器实例的类型不是创建实例的生成器函数?也就是说,如果我们有一个生成器,说是def G(): yield 1并且g是由G它创建的生成器实例g = G(),那么为什么是type(g) is G假的?

细节:

我最近问了一个关于如何确定给定生成器对象的生成器类型的问题.(参见在Python中,有没有办法测试生成器对象以找出哪个生成器创建它?.)答案最终需要使用__name__.但是,这仍然给我一个未解答的问题:为什么生成器不是Python中的类型?

下面的所有代码都考虑到了Python 3.3,但我相信大部分代码都适用于旧版本的Python(至少2.7版本)和更新版本,即3.4版本.

让我们看一个非常简单的迭代器示例,该迭代器首先作为类实现:

class C(object):
    def __iter__(self):
        return self

    def __next__(self):
        return 1


c = C()
print(next(c))       # 1
print(type(c))       # <class '__main__.C'>
print(type(c) is C)  # True
Run Code Online (Sandbox Code Playgroud)

在功能上,上面的类与下面给出的生成器相同.(当然,我们失踪了throw,send而且close,还有其他微妙的差异,但我认为它们与手头的问题无关.)

def G():
    while True:
        yield 1


g = G()
print(next(g))       # 1
print(type(g))       # <class 'generator'>
print(type(g) is G)  # False …
Run Code Online (Sandbox Code Playgroud)

python generator

3
推荐指数
1
解决办法
135
查看次数