Python Script для циклического перехода и создания переменных [duplicate]

Посмотрите, что я использую:

function monthDiff() {
    var startdate = Date.parseExact($("#startingDate").val(), "dd/MM/yyyy");
    var enddate = Date.parseExact($("#endingDate").val(), "dd/MM/yyyy");
    var months = 0;
    while (startdate < enddate) {
        if (startdate.getMonth() === 1 && startdate.getDate() === 28) {
            months++;
            startdate.addMonths(1);
            startdate.addDays(2);
        } else {
            months++;
            startdate.addMonths(1);
        }
    }
    return months;
}
229
задан Taryn 22 March 2017 в 17:21
поделиться

13 ответов

Вы можете использовать словари для этого. Словари - это хранилища ключей и ценностей.

>>> 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'

В тех случаях, когда вы думаете сделать что-то вроде

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 с целыми ключами, потому что списки поддерживают итерацию в порядке индекса, slicing , append и другие операции, которые потребуют неудобного управления ключами с помощью dict.

189
ответ дан user2357112 16 August 2018 в 01:35
поделиться

Любой набор переменных также может быть завершен в классе. Переменные «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
1
ответ дан Alexey Rodimov 16 August 2018 в 01:35
поделиться

Я отвечаю на вопрос: Как получить значение переменной, учитывая ее имя в строке? , которая закрыта как дубликат со ссылкой на этот вопрос.

Если рассматриваемые переменные являются частью объекта (например, части класса), то некоторые полезные функции для достижения именно этого: 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

"на самом деле не является начальным"

3
ответ дан Community 16 August 2018 в 01:35
поделиться

Используйте функцию встроенного getattr , чтобы получить атрибут объекта по имени. Измените имя по мере необходимости.

obj.spam = 'eggs'
name = 'spam'
getattr(obj, name)  # returns 'eggs'
63
ответ дан davidism 16 August 2018 в 01:35
поделиться
  • 1
    Это отлично работает с namedtuple – kap 26 June 2015 в 08:29
  • 2
    Прекрасный. Это именно то, что мне нужно. У меня есть объект и вам нужно получить доступ к переменным с помощью строки, и я не хотел использовать eval. Благодаря! – rayryeng 19 November 2016 в 00:01

Консенсус заключается в использовании словаря для этого - см. другие ответы. Это хорошая идея для большинства случаев, однако есть много аспектов, связанных с этим:

  • вы сами будете нести ответственность за этот словарь, включая сбор мусора (из переменных in-dict) и т. Д. .
  • нет никакой локальности или глобальности для переменных переменных, это зависит от глобальности словаря
  • , если вы хотите переименовать имя переменной, вам придется сделать это вручную
  • однако вы гораздо более гибкие, например вы можете решить перезаписать существующие переменные или ... ... выбрать реализацию константных переменных для создания исключения при перезаписи для разных типов и т. д.

Тем не менее, я реализовал variable variables manager -класс, который предоставляет некоторые из вышеперечисленных идей. Он работает для python 2 и 3.

Вы использовали бы класс следующим образом:

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)
1
ответ дан DomTomCat 16 August 2018 в 01:35
поделиться
  • 1
    На первый взгляд, длинный верблюжий импорт заставил меня подумать, что это была Ява. – markroxor 19 February 2018 в 07:17

Если вы не хотите использовать какой-либо объект, вы можете использовать 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
6
ответ дан Guillaume Lebreton 16 August 2018 в 01:35
поделиться
  • 1
    Для меня это звучит лучше, чем при использовании «exec». – fralau 30 December 2017 в 22:13
  • 2
    Однако это не работает с переменной __dict__. Интересно, существует ли общий механизм для создания глобальной переменной any динамически. – Alexey 30 January 2018 в 19:25
  • 3
    globals() может это сделать – Guillaume Lebreton 31 January 2018 в 08:42

Класс 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
2
ответ дан lukess 16 August 2018 в 01:35
поделиться

Вместо словаря вы также можете использовать 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
10
ответ дан ojas mohril 16 August 2018 в 01:35
поделиться

Всякий раз, когда вы хотите использовать переменные переменные, вероятно, лучше использовать словарь. Поэтому вместо записи

$foo = "bar"
$$foo = "baz"

вы пишете

mydict = {}
foo = "bar"
mydict[foo] = "baz"

Таким образом, вы не будете случайно перезаписывать ранее существовавшие переменные (что является аспектом безопасности), и вы можете иметь разные " Пространства имен». [/ д2]

29
ответ дан sepp2k 16 August 2018 в 01:35
поделиться

Новые кодеры иногда пишут такой код:

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 для мешка с именами со связанными значениями.

14
ответ дан TigerhawkT3 16 August 2018 в 01:35
поделиться

Для достижения этого поведения вы должны использовать 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
52
ответ дан Vallentin 16 August 2018 в 01:35
поделиться
  • 1
    Не забывайте упоминать, что вы не можете изменять переменные через locals () ( docs.python.org/library/functions.html#locals ). – Glenn Maynard 3 September 2009 в 19:43
  • 2
    Вы не можете устанавливать переменные таким образом. Вы не можете сделать globals()['a'] = 10. – sudo 6 June 2016 в 18:51
  • 3
    Thx, также работающий с locals () ['x'] = "xxx" – oxidworks 2 January 2017 в 17:10
  • 4
    @oxidworks Нет, это не работает. Тем не менее, он может казаться работать, если вы находитесь в глобальном контексте, где locals() просто возвращает globals() dict. – PM 2Ring 17 November 2017 в 13:20
52
ответ дан Vallentin 6 September 2018 в 00:56
поделиться
-1
ответ дан Sam Arthur Gillam 29 October 2018 в 07:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: