Путь классов Apache Spark построен динамически (для размещения кода пользователя для каждого приложения), что делает его уязвимым для таких проблем. @ user7337271 ответ правильный, но есть еще несколько проблем, в зависимости от используемого вами менеджера кластера («мастер»).
Во-первых, приложение Spark состоит из из этих компонентов (каждый из них является отдельным JVM, поэтому потенциально содержит разные классы в его пути к классам):
SparkSession
(или SparkContext
) и подключение к диспетчеру кластера для выполнения фактической работы Соотношение между ними описано на этой диаграмме из обзора режима кластера Apache Spark :
Теперь - какие классы должны находиться в каждом из этих компонентов?
На это может ответить следующая диаграмма:
Давайте разберем это медленно:
Теперь, когда мы получили это прямо, как мы получаем, чтобы классы правильно загружались в каждом компоненте, и какими правилами они должны следовать?
spark.yarn.archive
или spark.yarn.jars
параметры при использовании YARN). Банки / архив, которые вы предоставляете, должны включать все зависимости Spark (включая транзитивные зависимости), и они будут отправляться диспетчером кластера каждому исполнителю при запуске приложения. spark.jars
. Подводя итог, рассмотрим предлагаемый подход к созданию и развертыванию Spark Application (в данном случае - с использованием YARN):
spark.jars
при запуске SparkSession
lib/
загруженных двоичных файлов Spark в качестве значения spark.yarn.archive
Если вы действительно хотите создать их на лету, вы можете назначить dict, который возвращается либо globals (), либо locals () в зависимости от того, какое пространство имен вы хотите создать в них:
globals()['somevar'] = 'someval'
print somevar # prints 'someval'
Но я бы не рекомендовал это делать. В общем, избегайте глобальных переменных. Использование locals () часто просто скрывает то, что вы на самом деле делаете. Вместо этого создайте свой собственный dict и назначьте его.
mydict = {}
mydict['somevar'] = 'someval'
print mydict['somevar']
Изучите python zen; запустите это и запомните его:
>>> import this
У меня возникла ваша проблема, и вот мой ответ:
prices = [5, 12, 45]
list=['1','2','3']
for i in range(1,3):
vars()["prices"+list[0]]=prices[0]
print ("prices[i]=" +prices[i])
, поэтому при печати:
price1 = 5
price2 = 12
price3 = 45
vars()["prices"+str(i)]
и иметь переменную с ожидаемым именем.
– tripleee
30 January 2018 в 07:04
На объекте вы можете достичь этого с помощью setattr
>>> class A(object): pass
>>> a=A()
>>> setattr(a, "hello1", 5)
>>> a.hello1
5
Хотя я не вижу большого смысла, вот он:
for i in xrange(0, len(prices)):
exec("price%d = %s" % (i + 1, repr(prices[i])));
exec()
на print()
.
– Tim Čas
10 June 2013 в 17:06
repr()
пытается вернуть значение, которое при передаче в eval()
(или exec()
в этом случае) дает объект с одинаковое значение. В случае строк это ускользает от них должным образом. THAT SAID i>, вы никогда не должны использовать вышеприведенный код (у Python есть отличная концепция для представления кучи переменных --- списков!).
– Tim Čas
11 May 2015 в 13:53
бит длинный, он работает, я думаю ...
prices = [5, 12, 45]
names = []
for i, _ in enumerate(prices):
names.append("price"+str(i+1))
dict = {}
for name, price in zip(names, prices):
dict[name] = price
for item in dict:
print(item, "=", dict[item])
Еще один пример, который действительно является вариантом другого ответа , поскольку он также использует словарь:
>>> vr={}
... for num in range(1,4):
... vr[str(num)] = 5 + num
...
>>> print vr["3"]
8
>>>
vr
, хотя? ваше решение побеждает всю цель. я очищаю данные из Интернета, с которыми мне нужно создавать экземпляры класса для каждого элемента контейнера, а количество элементов контейнера неизвестно ... как в вопросе 2 в этот поток, который я создал
– Anthony
29 June 2018 в 00:48