【问题标题】:Nested functions not working, why?嵌套函数不起作用,为什么?
【发布时间】:2013-05-01 03:42:44
【问题描述】:

这是我的函数,它应该将另一个函数应用于给定迭代中的每个元素。

def transform(iterable,f):
        all=(i for i in iterable)
        return (e.f() for e in all)

for i in transform('abCdeFg','upper'):
      print(i,end='')

它应该做的是将所有字母大写,但我得到一个错误。我究竟做错了什么?我正在使用 Python 3.3。

【问题讨论】:

  • 当您说“我遇到错误”时,您必须告诉我们错误是什么。否则,我们只能自己猜测或尝试弄清楚。
  • 不要使用all 作为变量名。您将覆盖内置的all

标签: python python-3.3 nested-function


【解决方案1】:

e.f 字面意思是e.f。它与您的 f 变量无关。要按名称获取属性,请使用getattr

def transform(iterable,f):
        all=(i for i in iterable)
        return (getattr(e, f)() for e in all)

for i in transform('abCdeFg','upper'):
      print(i,end='')

此外,您可能会发现内置的 map 函数很有用:

def function(l):
    return l.upper()

for i in map(function, 'abCdeFg'):
    print(i, end='')

【讨论】:

    【解决方案2】:

    你犯了两个错误:

    • 要在参数 e 上调用函数 f,请执行 f(e),而不是 e.f()
    • 将函数作为参数给出,给出它的名字,而不是一个带有名字的字符串

    所以修正后的版本是:

       def transform(iterable, f):
         return (f(i) for i in iterable)
    
       for i in transform('abCdeFg', str.upper):
         print(i, end='')
    

    【讨论】:

      【解决方案3】:

      错误在这一行:

      return (e.f() for e in all)
      

      问题是str变量e没有方法f()。你应该改为:

      def transform(iterable,f):
              all=(i for i in iterable)
              return (f(e) for e in all)
      
      for i in transform('abCdeFg',str.upper):
            print(i,end='')
      

      【讨论】:

        【解决方案4】:

        如果你想按照你写的那样做,你需要这样做:

        def transform(s,f):
            return getattr(type(s), f)(s)
        
        
        for i in transform('abCdeFg','upper'):
              print(i,end='')
        

        打印:

        ABCDEFG
        

        正如其他人所说,这更直接:

        print('abCdeFg'.upper())
        

        您也不应该使用 Python 内置函数作为名称。 (即,避免调用genex all,因为您将覆盖内置函数all。)

        使用 getattr 你也可以返回一个没有给定方法的类型的默认值:

        >>> def transform(s,f):
        ...     return getattr(type(s), f, lambda s: 'no bueno')(s)
        >>> transform(1,'upper')
        'no bueno'
        

        或者使用try / except:

        >>> def transform(s,f):
        ...     try:
        ...         return getattr(type(s), f)(s)
        ...     except AttributeError as e:
        ...         return e
        ... 
        >>> transform(1,'upper')
        AttributeError("type object 'int' has no attribute 'upper'",)
        

        您也可以将 join 与 map 一起使用:

        >>> ''.join(map(lambda c: str.upper(c), 'abCdeFg'))
        'ABCDEFG'
        

        或加入理解:

        >>> ''.join(c.upper() for c in 'abCdeFg')
        'ABCDEFG'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-12-08
          • 2022-06-10
          • 1970-01-01
          • 1970-01-01
          • 2017-09-06
          • 1970-01-01
          • 1970-01-01
          • 2017-06-01
          相关资源
          最近更新 更多