【问题标题】:Python: string manipulation not working inside a functionPython:字符串操作在函数内部不起作用
【发布时间】:2015-12-24 02:01:56
【问题描述】:

代码如下:

def url_is_image(url):
    if url[-4:] in ['.jpg', '.png']:
        return True
    elif 'imgur' in url:
        url += '.jpg'
        return True
    else:
        return False

u1 = 'http://i.imgur.com/jtboy'
url_is_image(u1)
print u1

输出为“http://i.imgur.com/jtboy”,不带 .jpg 扩展名。关于为什么我的函数(第 5 行)未能将 .jpg 添加到字符串的任何想法?谢谢

【问题讨论】:

  • 请先修正缩进!
  • 你只是在url_is_image里面改变url ...
  • 我会将if url[-4:] in ['.jpg', '.png']: 替换为更清晰的if url.endswith(('.jpg', '.png')):

标签: python string function


【解决方案1】:

参数url 的范围是函数调用的本地范围。对其赋值不会影响函数外的任何变量或值。

变量u1 被分配一次。函数调用不影响它。然后打印出来。

由于你没有测试函数返回值的真实性,你可以这样重写:

def url_is_image(url):
    if url[-4:] in ['.jpg', '.png']:
        return url
    elif 'imgur' in url:
        return url + '.jpg'
    else:
        return url

u1 = 'http://i.imgur.com/jtboy'
u1 = url_is_image(u1)
print u1

然而,在这种情况下,函数名称具有误导性。由于我不知道您希望如何真正使用该功能,因此很难提出更好的解决方案。也许您想返回一个包含布尔值和修改后的字符串的 2 元组。



附录:根据您在此处评论中概述的目的,我会考虑一个仅返回有趣 URL 的函数。例如:

def consider_url(url):
    if url[-4:] in ['.jpg', '.png']:
        return url
    elif 'imgur' in url:
        return url + '.jpg'
    else:
        return None

然后您可以使用它来转换有趣的 URL 并忽略不感兴趣的 URL。

for url in some_list:
    url = consider_url(url)
    if url is None:
        continue
    print(url)

另一种方法是编写一个只为您提供有趣 url 的生成器:

def interesting_urls(iter):
    for url in iter:
        if url[-4:] in ['.jpg', '.png']:
            yield url
        elif 'imgur' in url:
            yield url + '.jpg'

然后您可以更简洁地处理您的网址:

for url in interesting_urls(some_list):
    print(url)

这些示例假设您已经以某种方式检索了列表或其他可迭代对象中的 URL。您可以使用如下所示的简单列表进行尝试。尽管列表中的大多数字符串都不是有效的 URL,但它们确实执行了上述函数的逻辑。

some_list = [
    "foo", "bar.jpg", "something/imgur/baz", "uninteresting", 'http://i.imgur.com/jtboy'
]

【讨论】:

  • 函数名意味着一个布尔返回。但他在下面使用它意味着一个字符串返回:u1 = url_is_image(u1)。为什么要将 u1 设置为布尔值?
  • @jphollowed:OP 在对另一个答案的评论中提到了这样的事情。
  • 谢谢,我现在明白了。我已将 URL 的修复移至其他位置,因此我不会尝试测试 URL 并同时更改它。该功能将用于来自 subreddit 主页的链接列表。通过此函数传递页面上的每个链接,我可以将图像链接(我感兴趣的链接)与其他链接分开。最后,我想要一个直接指向图像源的链接列表,这意味着它们必须以 .jpg 之类的图像扩展名结尾。我更改了这个函数,所以它只是一个测试,然后在使用 if 语句后,如有必要,我会操作字符串。
  • @couragewolf 好的,上下文有帮助。在代码维护和性能方面,我喜欢避免重复的逻辑和线性搜索(即 url 中的“if“imgur”)。我在答案中添加了两个实现这一点的设计示例。其他一些答案显示了如何返回一个包含布尔标志以及修改后的字符串的二元组。我最喜欢基于生成器的过滤器。
  • @dsh 非常感谢您的附录,它很有帮助!
【解决方案2】:

试试这个:

def url_is_image(url):
    status = False
    ret = url
    if url[-4:] in ['.jpg', '.png']:
        status = True
    elif 'imgur' in url:
        ret = url + '.jpg'
        status = True

    return status, ret

u1 = 'http://i.imgur.com/jtboy'
stat, u1 = url_is_image(u1)  
print stat, u1

【讨论】:

  • 当然可以a="one"; a+="two"a 将是 "onetwo"
  • value += '.jpg' 是有效的 Python。当您使用此语法时,Python 不会就地修改字符串,而是创建一个新字符串并将其绑定到旧名称。
  • true - 我用文字来测试 - 我的错
  • 我也喜欢这种方式,即使它不那么明确
【解决方案3】:

您必须将“全局”关键字添加到您的函数中。只需在其最顶部添加一行“全局 url”即可。同时删除参数。

您尝试做的是“副作用”。该函数修改其范围之外的变量。这可能会让读者感到头疼,尤其是当您将函数命名为“url_is_image”时,读者只会期望检查而不是修改。

我建议将副作用移动到一个单独的函数“fix_imgur_jpg_url”,该函数将 url 作为参数并返回固定的 url。

【讨论】:

    【解决方案4】:

    因为当您将url 传递给url_is_image 时,它正在创建一个新的url 对象。修改您的退货声明。不要使用全局变量

    def url_is_image(url):
        if url[-4:] in ['.jpg', '.png']:
            return url
        elif 'imgur' in url:
            return url + '.jpg'
        else:
            return False
    
    u1 = 'http://i.imgur.com/jtboy'
    url_is_image(u1)
    print u1
    

    或者您可以将return False 替换为return None,具体取决于接下来会发生什么。

    【讨论】:

      【解决方案5】:

      您必须返回您在函数中所做的更改才能生效。

      编辑:遵循不返回不同类型的编程实践,之前的代码已被修改。

      def url_is_image(url):
          exit_code = 1
          if url.endswith(('.jpg', '.png')):
              pass #exit_code still 1.
          elif 'imgur' in url:
              url += '.jpg' #exit_code still 1.
          else:
              exit_code = 0 #url does not match requirements
          return url, exit_code
      
      u1 = 'http://i.imgur.com/jtboy'
      u1, stat = url_is_image(u1)
      if stat: #url has been modified or has required extension
          print (u1)
      

      【讨论】:

      • 我需要该函数在满足 elif 条件时返回 True。有没有办法做到这一点?
      • 您的意思是只在elif 块中返回True 还是可以返回类似元组(url, True) 的东西?
      • 我认为返回一个元组很麻烦。无需返回两条数据。而不是在某处显示if True,只需说if not Falseurl != None,这将检查以确保函数没有到达else
      • @jphollowed 返回一个元组并不比返回一个 dict 或任何其他对象更混乱 - 对于这种类型的调用它是完全有效的
      • @gkusner 我只是说没有理由,当您可以从第一条数据中判断它是否是图像时。返回一个布尔值是多余的和过度的。虽然我认为它也更明确。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-18
      • 2014-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-21
      相关资源
      最近更新 更多