理解其他类变量中的参考类变量 [英] Reference class variable in a comprehension of another class variable

查看:66
本文介绍了理解其他类变量中的参考类变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是一个简单的问题,但我无法对其进行唯一搜索.

This may be a simple question, but I'm having trouble making a unique search for it.

我有一个定义静态字典的类,然后尝试静态地定义该字典的子集.

I have a class that defines a static dictionary, then attempts to define a subset of that dictionary, also statically.

因此,作为一个玩具示例:

So, as a toy example:

class example(object): 
    first_d = {1:1,2:2,3:3,4:4} 
    second_d = dict((k,first_d[k]) for k in (2,3))

这会产生 NameError:全局名称"first_d"未定义

我应该如何进行参考?在其他情况下,似乎可以使用这种模式,例如:

How should I be making this reference? It seems this pattern works in other cases, eg:

class example2(object):
    first = 1
    second = first + 1

推荐答案

基本列表理解具有以下

A basic list comprehension has the following syntax

[expression for var in iterable]

在类内部发生列表理解时,该类的属性可以在 iterable 中使用.在Python2和Python3中是这样.

When a list comprehension occurs inside a class, the attributes of the class can be used in iterable. This is true in Python2 and Python3.

但是,可以在Python2的 expression 中使用(即访问)该类的属性,而在Python3中则不能.

However, the attributes of the class can be used (i.e. accessed) in expression in Python2 but not in Python3.

对于生成器表达式,这个故事有些不同:

The story is a bit different for generator expressions:

(expression for var in iterable)

尽管仍然可以从 iterable 访问类属性,但是不能从 expression 访问类属性.(对于Python2和Python3确实如此).

While the class attributes can still be accessed from iterable, the class attributes are not accessible from expression. (This is true for Python2 and Python3).

这可以总结如下:

                             Python2      Python3
Can access class attributes
--------------------------------------------------
list comp. iterable                Y            Y
list comp. expression              Y            N
gen expr. iterable                 Y            Y
gen expr. expression               N            N
dict comp. iterable                Y            Y
dict comp. expression              N            N

(字典理解在这方面的行为与生成器表达式相同.)

(Dict comprehensions behave the same as generator expressions in this respect.)

现在这与您的问题有何关系:

在您的示例中,

second_d = dict((k,first_d[k]) for k in (2,3))

发生 NameError 是因为无法从生成器表达式的 expression 部分访问 first_d .

a NameError occurs because first_d is not accessible from the expression part of a generator expression.

Python2的一种解决方法是将生成器表达式更改为列表理解:

A workaround for Python2 would be to change the generator expression to a list comprehension:

second_d = dict([(k,first_d[k]) for k in (2,3)])

但是,我发现这不是一个非常舒适的解决方案,因为该代码将在Python3中失败.

However, I don't find this a very comfortable solution since this code will fail in Python3.

您可以按照Joel Cornett的建议进行操作:

You could do as Joel Cornett suggests:

second_d = {k: v for k, v in first_d.items() if k in (2, 3)}

因为它在 iterable 中使用了 first_d ,而不是dict理解的 expression 部分.但是,如果 first_d 包含许多项目,则可能会遍历更多的项目.没关系,如果 first_d 很小,此解决方案可能就很好.

since this uses first_d in the iterable rather than the expression part of the dict comprehension. But this may loop through many more items than necessary if first_d contains many items. Neverthess, this solution might be just fine if first_d is small.

通常,您可以通过定义可以在类内部或外部定义的辅助函数来避免此问题:

In general, you can avoid this problem by defining a helper function which can be defined inside or outside the class:

def partial_dict(dct, keys):
    return {k:dct[k] for k in keys}

class Example(object):
    first_d = {1:1,2:2,3:3,4:4}
    second_d = partial_dict(first_d, (2,3))

class Example2(object):
    a = [1,2,3,4,5]
    b = [2,4]
    def myfunc(A, B):
        return [x for x in A if x not in B]
    c = myfunc(a, b)

print(Example().second_d)
# {2: 2, 3: 3}

print(Example2().c)
# [1, 3, 5]

函数之所以起作用,是因为它们定义了局部范围,可以从dict理解中访问此局部范围内的变量.

Functions work because they define a local scope and variables in this local scope can be accessed from within the dict comprehension.

这是在这里解释,但是我对此并不完全满意,因为它不能解释为什么表达式部分的行为与列表理解,生成器表达式或字典理解的 iterable 部分不同.

This was explained here, but I am not entirely comfortable with this since it does not explain why the expression part behaves differently than the iterable part of a list comprehension, generator expression or dict comprehension.

因此,我无法(完全)解释为什么 Python的行为方式,只是这就是它的行为方式.

Thus I can not explain (completely) why Python behaves this way, only that this is the way it appears to behave.

这篇关于理解其他类变量中的参考类变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆