0

我正在寻找一种在不更改字符串类型的情况下设置字符串值的方法。

class testStr(str):
    myattr = ""

# this works fine.
t = testStr("testing")
t.myattr = "Yay!"
print "String value is: '" + t + "' and its attr is set to '" + t.myattr + "'"

# obviously once this is done the type of t goes back to str
# and I lose the value of .myattr
t = "whatever"

如果可能的话,我希望 myattr 在字符串设置为新值时保持它的值。它不需要像 t = "whatever" 那样工作,但如果我将更多变量放入 testStr 类,我不想手动复制 myattr 的值等等。

编辑:这是我最终提出的解决方案。它满足了我的所有需求,我希望有一些更优雅的东西,但我对此仍然很满意:

class config:
    class ConfigItem(str):
        def __init__(self, value):
            super( str, self ).__init__()
            self.var1 = "defaultv1"
            self.var2 = "defaultv2"

    def __init__(self):
        self.configTree = {}

    def __getitem__(self, key):
        if ( self.configTree.has_key(key) ): 
            return self.configTree[key]
        return ""

    def __setitem__(self, key, value):
        if ( value.__class__.__name__ == "ConfigItem" ):
            self.configTree[key] = value
            return

        if ( value.__class__.__name__ == "str" ):
            item = None
            if ( self.configTree.has_key(key) ): 
                item = self.configTree[key]
                new_item = self.ConfigItem(value)
                for attr in item.__dict__:
                    new_item.__setattr__(attr, item.__getattribute__(attr))
                self.configTree[key] = new_item
            else: 
                item = self.ConfigItem(value)
                self.configTree[key] = item

# test it out
cfg = config()
cfg["test_config_item"] = "it didn't work."

cfg["test_config_item"].var1 = "it worked!"
cfg["test_config_item"] = "it worked!"
print cfg["test_config_item"]
print cfg["test_config_item"].var1

这允许将配置设置用作字符串,但如果需要,它仍然包含附加信息。

4

4 回答 4

2

该语句t = "whatever"不会“更改”包含的值t,而是重新绑定t到不同的对象。如果你想改变,t那么你必须通过一个属性来改变它,或者通过分配给一个属性或者通过调用一个方法。

于 2011-06-06T22:49:36.860 回答
1

问题(您已经发现)是 t 被分配给 str 类型的新对象,该对象没有 myattr。

我认为最简单的方法是简单地创建一个不从 str 继承但包含字符串成员以及“myattr”的类

于 2011-06-06T22:48:55.230 回答
0

你为什么不使用元组或列表?

>>> s = [ ["the string", 15], ["second string", 12] ]
>>> print s
[['the string', 15], ['second string', 12]]

>>> s[0][1] = 8;
>>> print s
[['the string', 8], ['second string', 12]]

>>> print s[0]
['the string', 8]

>>> print s[1]
['second string', 12]
于 2011-06-07T00:07:31.827 回答
0

你可以考虑这种方法。它似乎提供了您正在寻找的功能。

class testStr(object):
    def __init__(self, string, myattr = ""):
        self.string = string
        self.myattr = myattr

运行与您展示的相同的测试用例。

>>> from testStr import testStr
>>> t = testStr('testing')
>>> t.string
'testing'
>>> t.myattr = 'Yay!'
>>> t.myattr
'Yay!'
>>> t.string = 'whatever'
>>> t.string
'whatever'
>>> t.myattr
'Yay!'

或者,如果你真的想从 str 继承(但这真的不那么 Pythonic,也不能解决你的问题):

class testStr(str):
    def __init__(self, string, myattr = ""):
        super(testStr, self).__init__(string)
        self.myattr = myattr
于 2011-06-06T22:53:46.547 回答