#python #string #setvalue
#python #строка #setvalue
Вопрос:
Я ищу способ задать значение строки без изменения типа строки.
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», но я не хочу вручную копировать значения 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
Это позволяет использовать параметр конфигурации в виде строки, однако он по-прежнему содержит дополнительную информацию, если это было необходимо.
Комментарии:
1. Переменные Python не являются переменными в смысле C / C .
Ответ №1:
Оператор t = "whatever"
не «изменяет значение, содержащееся в t
«, а скорее повторно привязывает t
к другому объекту. Если вы хотите изменить t
, то вместо этого вы должны изменить его с помощью атрибута, либо присвоив атрибуту, либо вызвав метод.
Комментарии:
1. Я готов использовать метод для установки значения строки. Я просто не хотел выполнять ‘newt.myattr = oldt.myattr’ для перемещения по значению каждой переменной, потому что тогда мне придется обновлять функцию, чтобы делать это для каждого атрибута, который я добавляю в класс. Я надеялся на что-то более элегантное.
Ответ №2:
Проблема (с которой вы разобрались) заключается в том, что t присваивается новому объекту типа str, у которого нет myattr .
Я думаю, что самым простым способом сделать это было бы просто создать класс, который не наследуется от str, но содержит элемент string, а также ‘myattr’
Комментарии:
1. Я думаю, на что я действительно надеялся, так это на то, что класс str содержал внутреннюю функцию для изменения значения или переменной, которая содержала это значение ( я надеялся на __ value __ или что-то в этом роде)
2. Если вы хотите, чтобы объект имел строковое значение, тогда определите методы
__str__()
и / или__unicode__()
.3. @python5000 — Фактический буфер базовых символов не отображается, см. svn.pythonmac.org/python24/python24-fat/Include/unicodeobject.h если вам интересно @Ignacio — я думаю, он хочет установить это, а не иметь строковое значение
4. Строки Python неизменяемы, так что вам не повезло. У меня есть похожий класс, который присоединяет кортеж к строке, но мне никогда не нужно было заменять строку. Единственное, что меня беспокоит, это то, что запись
t = "test" strtuple("test2", 1, 2)
приводит к простому,str
потому чтоstr.__add__
оператор отбрасывает кортеж.t = strtuple("test", 1, 2) "test2"
тем не менее, это работает.
Ответ №3:
Вы могли бы рассмотреть этот подход. Кажется, это обеспечивает функциональность, которую вы ищете.
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
Комментарии:
1. Да, именно так все и началось. У меня было именно то, что вы описали, однако теперь моя цель в жизни — создать версию, в которой вы все еще можете печатать t и получать «ура!» и по-прежнему получать доступ к .myattr, даже если мне нужно создать функцию t.setValue («что угодно»).
2. @python5000 Ты имеешь в виду, напечатать t и получить ‘testing’? Зачем вам это нужно делать? Что не так с установкой t.string, t.myattr и расширением по мере необходимости? Вы всегда можете создать t.setValue(‘whatever’), чтобы он изменял self.string и оставлял myattr в покое.
Ответ №4:
Почему вы не используете кортеж или список?
>>> 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]