【问题标题】:Why and how to resolve shadows argument name from outer scope in class (python)?为什么以及如何从类(python)中的外部范围解析阴影参数名称?
【发布时间】:2020-09-14 16:26:28
【问题描述】:

为什么以及如何从类(python)的外部范围解析阴影参数名称?

from optparse import OptionParser

class Test(object):
   def __init__(self):
      pass

   def _test1(self, some_val):
      print(some_val)

   def main(self, some_val):
      self.test1(some_val)

if __name__ == "__main__":
   parser = OptionParser()
   parser.add_option("-a", "--abcd", dest="abcd", default=None,
                      help="some_val")

   (options, args) = parser.parse_args()
   some_val = options.abcd

   mainobj = Test()
   mainobj.main(some_val)

在上面的代码中

  1. 'main''_test' 中的参数 'some_val',从外部范围显示阴影 'some_val'
  2. 在方法 '_test' 中,显示 '_test' 可能是静态的。

Pycharm,Python 3.8

为什么是那些?我该如何解决它们?

【问题讨论】:

标签: python python-3.x pycharm


【解决方案1】:

'main' 和 '_test' 中的参数 'some_val' ,从外部范围显示阴影 'some_val'。

您已在全局范围内声明了一个 some_val 变量:

some_val = options.abcd

由于此变量是全局变量,因此通常可以从模块中的任何位置访问它。

但是您的 Test._test1Test.main 方法定义了只能从方法主体访问的 some_val 参数:它们在方法本地范围内。

此警告只是通知您some_val 参数隐藏("shadowing"some_val 全局变量,并且您将无法从方法主体访问全局变量(因为 some_val将引用本地参数)。

从技术上讲,如果您不需要从方法体中访问全局 some_val 变量,那不是问题。

您可以通过简单地为变量/参数提供更好的名称来解决此警告,而不是为全局变量和局部变量重复使用相同的名称。


在方法 '_test' 中,显示的 '_test' 可能是静态的

此警告意味着,由于您的 Test1._test 方法不使用 self 参数,因此可以使用 staticmethod 装饰器将其声明为静态(请参阅 this other SO question 中的更多详细信息):

@staticmethod
def _test1(some_val):
    print(some_val)

【讨论】:

    【解决方案2】:
    • 正如其他人所解释的,您有两个名为 some_val 的变量,从技术上讲,它们可以在代码的同一部分中可见; PyCharm 会就此向您发出警告,因为有两个同名的不同变量可能会造成混淆。

      在这种情况下,解决方案是将if __name__ == '__main__'之后的代码放入一个函数中,并且只在if之后调用该函数;这会将代码的该部分中使用的变量移动到本地范围内,因此它们不会与其他地方的变量混淆:

      def main():
         parser = OptionParser()
         parser.add_option("-a", "--abcd", dest="abcd", default=None,
                            help="some_val")
      
         (options, args) = parser.parse_args()
         some_val = options.abcd
      
         mainobj = Test()
         mainobj.main(some_val)
      
      if __name__ == "__main__":
          main()
      

      您也可以仅部分执行此操作,如下所示:

      def get_some_val():
         parser = OptionParser()
         parser.add_option("-a", "--abcd", dest="abcd", default=None,
                            help="some_val")
      
         (options, args) = parser.parse_args()
         return options.abcd
      
      if __name__ == "__main__":
         mainobj = Test()
         mainobj.main(get_some_val())
      
    • _test 方法没有使用self 参数。

      如果是这样,您可以将其标记为 @staticmethod 并省略 self

      @staticmethod
      def _test1(some_val):
          print(some_val)
      

      或者,扩展该方法,使其实际上使用self(您可能一直计划这样做)。

    【讨论】:

      猜你喜欢
      • 2015-10-13
      • 2021-10-03
      • 2013-12-06
      • 2011-02-17
      • 2021-05-22
      • 2018-08-12
      • 1970-01-01
      • 2018-07-16
      相关资源
      最近更新 更多