程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

理解其他类变量中的参考类变量

发布于2019-10-14 21:11     阅读(1048)     评论(0)     点赞(29)     收藏(5)


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

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

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

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: global name 'first_d' is not defined

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

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

解决方案


基本列表理解具有以下语法

[expression for var in iterable]

当列表理解发生在类内部时,可以在中使用类的属性iterable在Python2和Python3中确实如此。

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

生成器表达式的故事有点不同:

(expression for var in iterable)

虽然仍然可以从访问iterable类属性,但不能从访问类属性expression(对于Python2和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

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


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

在您的示例中

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

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

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

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

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

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

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

因为这用first_ddict理解iterable而不是expression部分中。但是,如果first_d包含许多项目,这可能会遍历比所需更多的项目。没什么,如果first_d很小的话,这个解决方案可能很好

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

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理解中访问该局部作用域中的变量。

此处已对此进行了解释,但是我对此并不完全满意,因为它无法解释为什么该expression部分的行为与iterable列表理解,生成器表达式或dict理解部分不同

因此,我无法(完全地)解释为什么 Python会这样表现,而无法解释这就是它的表现方式。



所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:https://www.pythonheidong.com/blog/article/136836/bffef4dedfba720f2a16/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

29 0
收藏该文
已收藏

评论内容:(最多支持255个字符)