ниже логика будет извлекать разницу в месяцах
(endDate.getFullYear()*12+endDate.getMonth())-(startDate.getFullYear()*12+startDate.getMonth())
Вы можете использовать словари, чтобы выполнить это. Словари - это хранилища ключей и ценностей.
>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'y': 2, 'x': 1, 'z': 3}
>>> dct["y"]
2
Вы можете использовать имена переменных ключей для достижения влияния переменных переменных без риска для безопасности.
>>> x = "spam"
>>> z = {x: "eggs"}
>>> z["spam"]
'eggs'
В тех случаях, когда вы думаете сделать что-то вроде [ ! d2] var1 = 'foo'
var2 = 'bar'
var3 = 'baz'
...
список может быть более уместным, чем dict. Список представляет упорядоченную последовательность объектов с целыми индексами:
l = ['foo', 'bar', 'baz']
print(l[1]) # prints bar, because indices start at 0
l.append('potatoes') # l is now ['foo', 'bar', 'baz', 'potatoes']
Для упорядоченных последовательностей списки удобнее, чем dict с целыми ключами, потому что списки поддерживают итерацию в порядке индекса, нарезки, append , и другие операции, которые потребуют неудобного управления ключами с помощью dict.
Любой набор переменных также может быть завершен в классе. Переменные «Variable» могут быть добавлены к экземпляру класса во время выполнения, напрямую обращаясь к встроенному словарю через атрибут __dict__.
Следующий код определяет класс Variables, который добавляет переменные (в этом случае атрибуты) к своему экземпляру во время построения. Имена переменных берутся из указанного списка (который, например, мог быть сгенерирован программным кодом):
# some list of variable names
L = ['a', 'b', 'c']
class Variables:
def __init__(self, L):
for item in L:
self.__dict__[item] = 100
v = Variables(L)
print(v.a, v.b, v.c)
#will produce 100 100 100
Я отвечаю на вопрос: Как получить значение переменной, учитывая ее имя в строке? , которая закрыта как дубликат со ссылкой на этот вопрос.
Если рассматриваемые переменные являются частью объекта (например, части класса), то некоторые полезные функции для достижения именно этого: hasattr
, getattr
и setattr
.
Так, например, вы можете иметь:
class Variables(object):
def __init__(self):
self.foo = "initial_variable"
def create_new_var(self,name,value):
setattr(self,name,value)
def get_var(self,name):
if hasattr(self,name):
return getattr(self,name)
else:
raise("Class does not have a variable named: "+name)
Тогда вы можете сделать:
v = Variables()
v.get_var("foo")
"initial_variable"
< / blockquote>v.create_new_var(v.foo,"is actually not initial") v.initial_variable
"на самом деле не является начальным"
blockquote>
Используйте встроенную функцию getattr, чтобы получить атрибут объекта по имени. Измените имя по мере необходимости.
obj.spam = 'eggs'
name = 'spam'
getattr(obj, name) # returns 'eggs'
Консенсус заключается в использовании словаря для этого - см. другие ответы. Это хорошая идея для большинства случаев, однако есть много аспектов, связанных с этим:
вы сами будете нести ответственность за этот словарь, включая сбор мусора (из переменных в-dict) и т. Д. Есть либо нет локальности или глобальности для переменных переменных, это зависит от глобальности словаря, если вы хотите переименовать имя переменной, вам придется делать это вручную, однако вы гораздо более гибкие, например вы можете решить перезаписать существующие переменные или ... ... выбрать для реализации константных переменных для создания исключения при перезаписи для разных типов и т. д.Тем не менее, я применил переменный переменный менеджер-класс который обеспечивает некоторые из вышеуказанных идей. Он работает для python 2 и 3.
Вы использовали бы variable variables manager следующим образом:
from variableVariablesManager import VariableVariablesManager
myVars = VariableVariablesManager()
myVars['test'] = 25
print(myVars['test'])
# define a const variable
myVars.defineConstVariable('myconst', 13)
try:
myVars['myconst'] = 14 # <- this raises an error, since 'myconst' must not be changed
print("not allowed")
except AttributeError as e:
pass
# rename a variable
myVars.renameVariable('myconst', 'myconstOther')
# preserve locality
def testLocalVar():
myVars = VariableVariablesManager()
myVars['test'] = 13
print("inside function myVars['test']:", myVars['test'])
testLocalVar()
print("outside function myVars['test']:", myVars['test'])
# define a global variable
myVars.defineGlobalVariable('globalVar', 12)
def testGlobalVar():
myVars = VariableVariablesManager()
print("inside function myVars['globalVar']:", myVars['globalVar'])
myVars['globalVar'] = 13
print("inside function myVars['globalVar'] (having been changed):", myVars['globalVar'])
testGlobalVar()
print("outside function myVars['globalVar']:", myVars['globalVar'])
Если вы хотите разрешить переписывание переменных с одним и тем же типом:
myVars = VariableVariablesManager(enforceSameTypeOnOverride = True)
myVars['test'] = 25
myVars['test'] = "Cat" # <- raises Exception (different type on overwriting)
Если вы не хотите использовать какой-либо объект, вы все равно можете использовать setattr() внутри вашего текущего модуля:
import sys
current_module = module = sys.modules[__name__] # i.e the "file" where your code is written
setattr(current_module, 'variable_name', 15) # 15 is the value you assign to the var
print(variable_name) # >>> 15, created from a string
__dict__
. Интересно, существует ли общий механизм для создания глобальной переменной any i> динамически.
– Alexey
30 January 2018 в 19:25
Класс SimpleNamespace может использоваться для создания новых атрибутов с помощью setattr или подкласса SimpleNamespace и создания вашей собственной функции для добавления новых имен атрибутов (переменных).
from types import SimpleNamespace
variables = {"b":"B","c":"C"}
a = SimpleNamespace(**v)
setattr(a,"g","G")
a.g = "G+"
something = a.a
Вместо словаря вы также можете использовать namedtuple из модуля коллекций, что облегчает доступ.
например:
#using dictionary
variables = {}
variables["first"] = 34
variables["second"] = 45
print variables["first"], variables["second"]
#using namedtuple
Variables = namedtuple('Variables', ['first', 'second'])
vars = Variables(34, 45)
print vars.first, vars.second
Всякий раз, когда вы хотите использовать переменные переменные, вероятно, лучше использовать словарь. Поэтому вместо записи
$foo = "bar"
$$foo = "baz"
вы пишете
mydict = {}
foo = "bar"
mydict[foo] = "baz"
Таким образом, вы не будете случайно перезаписывать ранее существовавшие переменные (что является аспектом безопасности), и вы можете иметь разные " Пространства имен».
Новые кодеры иногда пишут такой код:
my_calculator.button_0 = tkinter.Button(root, text=0)
my_calculator.button_1 = tkinter.Button(root, text=1)
my_calculator.button_2 = tkinter.Button(root, text=2)
...
Затем кодер остается с кучей именованных переменных с усилием кодирования O (m * n), где m - число именованных переменных, а n - количество раз, к которому необходимо получить доступ к группе переменных (включая создание). Более проницательный новичок отмечает, что единственная разница в каждой из этих строк - это число, которое изменяется на основе правила и решает использовать цикл. Однако они зациклились на том, как динамически создавать эти имена переменных, и могут попробовать что-то вроде этого:
for i in range(10):
my_calculator.('button_%d' % i) = tkinter.Button(root, text=i)
Вскоре они обнаруживают, что это не работает.
Если программа требует произвольных переменных «имена», лучше всего подходит словарь, как объясняется в других ответах. Однако, если вы просто пытаетесь создать много переменных, и вы не возражаете ссылаться на них с последовательностью целых чисел, вы, вероятно, ищете list. Это особенно верно, если ваши данные однородны, например, ежедневные показания температуры, еженедельные оценки викторины или сетка графических виджетов.
Это можно собрать следующим образом:
my_calculator.buttons = []
for i in range(10):
my_calculator.buttons.append(tkinter.Button(root, text=i))
Этот list также может быть создан в одной строке с пониманием:
my_calculator.buttons = [tkinter.Button(root, text=i) for i in range(10)]
Результат в любом случае - это заполненный list, причем первый элемент имеет доступ к my_calculator.buttons[0], следующий с my_calculator.buttons[1] и т. д. Имя переменной «base» становится именем list, и для доступа к нему используется различный идентификатор.
Наконец, не забудьте другие структуры данных, такие как set - это аналогично словарю, за исключением того, что каждое «имя» не имеет привязанного к нему значения. Если вам просто нужна «сумка» объектов, это может быть отличным выбором. Вместо этого:
keyword_1 = 'apple'
keyword_2 = 'banana'
if query == keyword_1 or query == keyword_2:
print('Match.')
У вас будет следующее:
keywords = {'apple', 'banana'}
if query in keywords:
print('Match.')
Используйте последовательность list для последовательности похожих объектов, a set для произвольного - помещенный пакет предметов или dict для мешка с именами со связанными значениями.
Для достижения этого поведения вы должны использовать встроенный метод globals():
def var_of_var(k, v):
globals()[k] = v
print variable_name # NameError: name 'variable_name' is not defined
some_name = 'variable_name'
globals()[some_name] = 123
print variable_name # 123
some_name = 'variable_name2'
var_of_var(some_name, 456)
print variable_name2 # 456