Установить значение строки без указания типа str? - PullRequest
0 голосов
/ 07 июня 2011

Я ищу способ установить значение строки без изменения типа строки.

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 = "что угодно", но я не хочу вручную копировать значения myattr и многое другое, если я добавлю больше переменных в класс testStr.

РЕДАКТИРОВАТЬ: Вот решение, которое я в конечном итоге придумал. Это удовлетворяет всем моим потребностям, я надеялся на что-то более элегантное, но тем не менее, я доволен этим:

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 ]

2 голосов
/ 07 июня 2011

Оператор t = "whatever" не «изменяет значение, содержащееся в t», но скорее связывает t с другим объектом.Если вы хотите изменить t, вы должны вместо этого изменить его с помощью атрибута, либо присвоив атрибуту, либо вызвав метод.

1 голос
/ 07 июня 2011

Проблема (которую вы выяснили) состоит в том, что t присваивается новому объекту типа str, у которого нет myattr.

Я думаю, что самый простой способ сделать это - просто создать класс, который не наследуется от str, но содержит строковый член, а также 'myattr'

0 голосов
/ 07 июня 2011

Почему вы не используете кортеж или список?

>>> 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]
0 голосов
/ 07 июня 2011

Вы могли бы рассмотреть этот подход.Кажется, он обеспечивает необходимую вам функциональность.

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 (но это действительно менее питонно и также не решает вашу проблему):

class testStr(str):
    def __init__(self, string, myattr = ""):
        super(testStr, self).__init__(string)
        self.myattr = myattr
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...