使用 python 3.5 str.format 左截断? [英] Left truncate using python 3.5 str.format?

查看:24
本文介绍了使用 python 3.5 str.format 左截断?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问:是否可以使用 Python 3.5 的字符串格式语法来创建格式字符串以进行左截断?

基本上我想做的是拿一个 git SHA:

"c1e33f6717b9d0125b53688d315aff9cf8dd9977"

并且仅使用格式字符串,只显示正确的 8 个字符:

"f8dd9977"

我尝试过的事情:

无效语法

<预><代码>>>>"{foo[-8:]}".format(foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977")>>>"{foo[-8]}".format(foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977")>>>"{:8.-8}".format("c1e33f6717b9d0125b53688d315aff9cf8dd9977")

错误的结果

### 结果是前 8 个而不是后 8 个.>>>"{:8.8}".format("c1e33f6717b9d0125b53688d315aff9cf8dd9977")

有效但不灵活且麻烦

### 解决方案要求条形长度始终为 40.>>>bar="c1e33f6717b9d0125b53688d315aff9cf8dd9977">>>{foo[32]}{foo[33]}{foo[34]}{foo[35]}{foo[36]}{foo[37]}{foo[38]}{foo[39]}".format(foo=bar)

有人提出了类似的问题,但从未回答.但是我的不同之处在于我只能使用格式字符串,我无法更改输入参数的范围.这意味着以下是不可接受的解决方案:

<预><代码>>>>bar="c1e33f6717b9d0125b53688d315aff9cf8dd9977">>>"{0}".format(bar[-8:])

我应该澄清的另一个方面......以上解释了问题的最简单形式.在实际上下文中,问题更准确地表述为:

<预><代码>>>>导入操作系统>>>"foo {git_sha}".format(**os.environ)

我想向左截断git_sha"环境变量的地方.诚然,这比最简单的形式要复杂一些,但如果我能解决最简单的问题 - 我可以找到解决更复杂问题的方法.

解决方案

子类化 str 是一种选择吗?

foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977"类 CustomStr(str):def __format__(self, spec):如果规范 == 'trunc_left':返回自我[-8:]别的:返回 super().__format__(spec)s = CustomStr(foo)打印('{}'.format(s))打印('{:trunc_left}'.format(s))

从那里,您可以执行以下操作:

导入操作系统类 CustomStr(str):def __format__(self, spec):返回自我[-8:]类 OsEnvironWrapper(dict):def __init__(自我,环境):self.environ = 环境def __getitem__(self, key):如果键 == 'git_sha':返回 CustomStr(self.environ[key])别的:返回 self.environ[key]os_environ = OsEnvironWrapper(os.environ)打印('foo {git_sha}'.format(**os_environ))

我知道,包装器几乎无法接受,但您可以通过正确模拟容器类型来将其调整为透明.

对于不继承 strdict 的变体,请参阅 Jim 的解决方案.

Q: Is is possible to create a format string using Python 3.5's string formatting syntax to left truncate?

Basically what I want to do is take a git SHA:

"c1e33f6717b9d0125b53688d315aff9cf8dd9977"

And using only a format string, get the display only the right 8 chars:

"f8dd9977"

Things Ive tried:

Invalid Syntax

>>> "{foo[-8:]}".format(foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977")
>>> "{foo[-8]}".format(foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977")  
>>> "{:8.-8}".format("c1e33f6717b9d0125b53688d315aff9cf8dd9977")

Wrong Result

### Results in first 8 not last 8. 
>>> "{:8.8}".format("c1e33f6717b9d0125b53688d315aff9cf8dd9977")

Works but inflexible and cumbersome

### solution requires that bar is always length of 40.
>>> bar="c1e33f6717b9d0125b53688d315aff9cf8dd9977"
>>> "{foo[32]}{foo[33]}{foo[34]}{foo[35]}{foo[36]}{foo[37]}{foo[38]}{foo[39]}".format(foo=bar)

A similar question was asked, but never answered. However mine differs in that I am limited to using only format string, I don't have the ability to change the range of the input param. This means that the following is an unacceptable solution:

>>> bar="c1e33f6717b9d0125b53688d315aff9cf8dd9977"
>>> "{0}".format(bar[-8:])

One more aspect I should clarify... the above explains the simplest form of the problem. In actual context, the problem is expressed more correctly as:

>>> import os
>>> "foo {git_sha}".format(**os.environ)

Where I want to left_truncate "git_sha" environment variable. Admittedly this is a tad more complex than simplest form, but if I can solve the simplest - I can find a way to solve the more complex.

解决方案

Is subclassing str an option?

foo="c1e33f6717b9d0125b53688d315aff9cf8dd9977"

class CustomStr(str):
    def __format__(self, spec):
        if spec == 'trunc_left':
            return self[-8:]
        else:
            return super().__format__(spec)

s = CustomStr(foo)

print('{}'.format(s))
print('{:trunc_left}'.format(s))

From there, you can do something working like so:

import os

class CustomStr(str):
    def __format__(self, spec): 
       return self[-8:]

class OsEnvironWrapper(dict):
    def __init__(self, environ):
        self.environ = environ

    def __getitem__(self, key):
        if key == 'git_sha':
            return CustomStr(self.environ[key])
        else:
            return self.environ[key]

os_environ = OsEnvironWrapper(os.environ)
print('foo {git_sha}'.format(**os_environ))

I know, the wrapper is barely acceptable, but you can tweak it to be transparent by emulating a container type properly.

[edit] See Jim's solution for a variant that does not subclass str or dict.

这篇关于使用 python 3.5 str.format 左截断?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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