Принятый ответ работает, но немного больше объяснений не повредит.
Атрибуты класса не становятся атрибутами экземпляра при создании экземпляра. Они становятся атрибутами экземпляра, когда им присваивается значение.
В исходном коде значение no присваивается атрибуту list
после создания экземпляра; поэтому он остается атрибутом класса. Определение списка внутри __init__
работает, потому что __init__
вызывается после создания экземпляра. В качестве альтернативы, этот код также выдаст желаемый результат:
>>> class a:
list = []
>>> y = a()
>>> x = a()
>>> x.list = []
>>> y.list = []
>>> x.list.append(1)
>>> y.list.append(2)
>>> x.list.append(3)
>>> y.list.append(4)
>>> print(x.list)
[1, 3]
>>> print(y.list)
[2, 4]
Однако запутанный сценарий в вопросе никогда не случится с неизменяемыми объектами, такими как числа и строки, поскольку их значение не может быть изменено без назначения. Например, код, аналогичный оригиналу со строковым атрибутом, работает без каких-либо проблем:
>>> class a:
string = ''
>>> x = a()
>>> y = a()
>>> x.string += 'x'
>>> y.string += 'y'
>>> x.string
'x'
>>> y.string
'y'
Итак, чтобы суммировать: атрибуты класса становятся атрибутами экземпляра тогда и только тогда, когда им присваивается значение после создания, в методе __init__
или нет. Это хорошо, потому что таким образом вы можете иметь статические атрибуты, если никогда не присваиваете значение атрибуту после создания экземпляра.
Функция transform
в потоке Spark позволяет использовать любые преобразования Apache Spark на основе RDDs
для потока. map
используется для преобразования элемента в элемент, и его можно реализовать с помощью transform
. По существу, map
работает с элементами DStream
и transform
, позволяет работать с RDDs
DStream. Вы можете найти http://spark.apache.org/docs/latest/streaming-programming-guide.html#transformations-on-dstreams .
Функция преобразования в Spark Streaming позволяет выполнять любые преобразования в базовых RDD в потоке. Например, вы можете объединить два RDD в потоковой передаче с использованием Transform, в котором одним RDD будет некоторое RDD, сделанное из текстового файла или параллельной коллекции, а другое RDD поступает из Stream текстового файла / сокета и т. Д.
Карта работает с каждым элементом RDD в определенной партии и приводит к RDD после применения функции, переданной в Map.
map
является элементарным преобразованием, а transform
является преобразованием RDD
map (func): возвращает новый DStream путем прохождения каждый элемент источника DStream через функцию func.
blockquote>Вот пример, который демонстрирует операцию отображения и преобразования в DStream
val conf = new SparkConf().setMaster("local[*]").setAppName("StreamingTransformExample") val ssc = new StreamingContext(conf, Seconds(5)) val rdd1 = ssc.sparkContext.parallelize(Array(1,2,3)) val rdd2 = ssc.sparkContext.parallelize(Array(4,5,6)) val rddQueue = new Queue[RDD[Int]] rddQueue.enqueue(rdd1) rddQueue.enqueue(rdd2) val numsDStream = ssc.queueStream(rddQueue, true) val plusOneDStream = numsDStream.map(x => x+1) plusOneDStream.print()
в
map
добавляет 1 к каждому элементу во всех RDD в DStream, дает результат, как показано ниже------------------------------------------- Time: 1501135220000 ms ------------------------------------------- 2 3 4 ------------------------------------------- Time: 1501135225000 ms ------------------------------------------- 5 6 7 -------------------------------------------
transform
transform (func): Return новый DStream, применяя функцию RDD-to-RDD к каждому RDD исходного DStream. Это может быть использовано для выполнения произвольных операций RDD в DStream.
blockquote>val commonRdd = ssc.sparkContext.parallelize(Array(0)) val combinedDStream = numsDStream.transform(rdd=>(rdd.union(commonRdd))) combinedDStream.print()
transform позволяет выполнять RDD-операцию, такую как объединение, объединение и т. Д. На RDD внутри DStream, приведенный здесь примерный код будет выдавать выходной сигнал ниже
------------------------------------------- Time: 1501135490000 ms ------------------------------------------- 1 2 3 0 ------------------------------------------- Time: 1501135495000 ms ------------------------------------------- 4 5 6 0 ------------------------------------------- Time: 1501135500000 ms ------------------------------------------- 0 ------------------------------------------- Time: 1501135505000 ms ------------------------------------------- 0 -------------------------------------------
, здесь
commonRdd
, который содержит элемент0
, выполняется операция объединения со всеми лежащими в основе RDD в DStream.
DStream имеет несколько RDD, так как каждый интервал между пакетами является другим RDD. Таким образом, используя transform (), вы получаете возможность применить операцию RDD для всего DStream.
Пример из Spark Docs: http://spark.apache.org/docs/latest/streaming-programming-guide.html#transform-operation