【问题标题】:where does python store origin value for strpython在哪里存储str的原始值
【发布时间】:2017-08-25 05:13:03
【问题描述】:

我是 python 新手,我有一个简单的问题。

假设我创建了 str 的子类以将所有内容都更改为“测试”:

class Mystr(str):
    def __str__(self):
        return 'test'
    def __repr__(self):
        return 'test'

>>> mystr = Mystr(12345)
>>> print(mystr)
test
>>>
>>> print(mystr + 'test')
12345test

我想要的只是“测试”,但是 python在哪里存储原始值'12345'? 我在任何地方都找不到它。

>>> dir(mystr)
['__add__', '__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__module__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

检查后,我实际上在 getnewargs

中找到了它
>>> mystr.__getnewargs__()
('12345',)

然后我将其更改为:

class Mystr(str):
    def __str__(self):
        return 'test'
    def __repr__(self):
        return 'test'
    def __getnewargs__(self):
        return 'test'

>>> mystr = Mystr(12345)
>>> print(mystr)
test
>>> mystr.__getnewargs__()
'test'
>>> print(mystr + 'test')
12345test

为什么 12345 还在? python在哪里存储原始值'12345'?

Win32 上的 Python 3.6.1(v3.6.1:69c0db5,2017 年 3 月 21 日,18:41:36)[MSC v.1900 64 位(AMD64)]

【问题讨论】:

  • 您可能对tp_itemsize 的文档感兴趣。
  • 和往常一样,您可以通过直接调用基类方法来获取基类的行为:str.__str__(mystr)

标签: python string subclass


【解决方案1】:

它存储在selfself 是你的方法附加到的对象,也就是字符串。

【讨论】:

  • 具体在哪里?属性名称是什么?
  • 它不是一个属性。它是对象本身。
  • 哈哈...我终于意识到这个简单的事实。 ____str____ ___repr____ 只是它的虚假呈现,价值就是它本身,改变呈现不会改变任何东西。现在我知道实际上我应该通过更改__new____ 方法来更改值。谢谢
  • 可以通过覆盖 all 特殊方法来“伪造”具有不同值的字符串,例如__add____iter__ 等等。
【解决方案2】:

每当您将参数传递给类时,都会执行该类本地的内置函数 __getnewargs__。然后该函数将所有传递给类的变量初始化为参数并将它们存储在一个元组中。

现在,当您尝试将类对象(在您的情况下为 mystr)与字符串连接时,包含 ('12345',) 的元组返回其唯一的参数 '12345',即与字符串连接并打印为 '12345test'。

如果您尝试像这样打印它print(mystr + ' anything'),它将打印“12345 任何东西”

欲了解更多信息,请查看 this screenshot

【讨论】:

    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 2015-09-30
    • 1970-01-01
    • 2020-07-31
    • 2018-11-09
    • 1970-01-01
    相关资源
    最近更新 更多