Создайте функцию, которая создает для вас объекты и переменные [duplicate]

Все эти основные команды являются частью пакета coreutils.

Вы можете найти всю необходимую информацию здесь:

http: //www.gnu. org / software / coreutils /

Если вы хотите загрузить последний источник, вы должны использовать git:

git clone git://git.sv.gnu.org/coreutils

Чтобы установить git на вашей машине Ubuntu, вы должны использовать apt-get (git не входит в стандартную установку Ubuntu):

sudo apt-get install git

По правде говоря, здесь вы можете найти конкретный источник для команды ls:

http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/ls.c

Только 4984 строк кода для команды «достаточно легко» в качестве ls ... вы все еще интересуетесь чтением? Удачи! : D

216
задан Taryn 22 March 2017 в 17:21
поделиться

12 ответов

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

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

189
ответ дан user2357112 15 August 2018 в 13:00
поделиться

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

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

Если рассматриваемые переменные являются частью объекта (например, части класса), то некоторые полезные функции для достижения именно этого являются 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" v.create_new_var(v.foo,"is actually not initial") v.initial_variable

"initial_variable"

3
ответ дан Community 15 August 2018 в 13:00
поделиться

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

obj.spam = 'eggs'
name = 'spam'
getattr(obj, name)  # returns 'eggs'
63
ответ дан davidism 15 August 2018 в 13:00
поделиться
  • 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 15 August 2018 в 13:00
поделиться
  • 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 15 August 2018 в 13:00
поделиться
  • 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 15 August 2018 в 13:00
поделиться

Вместо словаря вы также можете использовать 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 15 August 2018 в 13:00
поделиться

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

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

вы пишете

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

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

29
ответ дан sepp2k 15 August 2018 в 13:00
поделиться

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

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 15 August 2018 в 13:00
поделиться

Для достижения этого поведения вы должны использовать встроенный метод 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 15 August 2018 в 13:00
поделиться
  • 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 5 September 2018 в 12:19
поделиться
Другие вопросы по тегам:

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