varargs / params object [], но различают фактический объект [] input и varargs input (s) [duplicate]

Из документов: https://spark.apache.org/docs/latest/api/python/pyspark.sql.html#pyspark.sql.DataFrameWriter Поскольку v1.4

csv(path, mode=None, compression=None, sep=None, quote=None, escape=None, header=None, nullValue=None, escapeQuotes=None, quoteAll=None, dateFormat=None, timestampFormat=None)

, например

from pyspark.sql import DataFrameWriter
.....
df1 = sqlContext.createDataFrame(query1)
df1.write.csv(path="/opt/Output/sqlcsvA.csv", mode="append")

Если вы хотите записать один файл, вы можете использовать coalesce или repartition на любой из этих строк. Не имеет значения, какая строка, потому что dataframe является просто выполнением DAG, выполнение не выполняется до записи в csv. repartition & amp; coalesce эффективно используют один и тот же код, но объединение может только уменьшить количество разделов, где repartition также может увеличить их. Я просто придерживался repartition для простоты.

, например

df1 = sqlContext.createDataFrame(query1).repartition(1)

или

df1.repartition(1).write.csv(path="/opt/Output/sqlcsvA.csv", mode="append")

Я думаю, что примеры в документах aren ' t велика, они не показывают примеры использования параметров, отличных от пути.

Ссылаясь на две вещи, которые вы пробовали:

(append)

Для что для работы должна существовать строковая переменная с именем append, содержащая значение «append». В библиотеке DataFrameWriter, называемой append, нет строковой константы. т. е. вы могли бы добавить это ранее в свой код, и тогда это сработает. append = "append"

('mode=append')

Для этого для метода csv необходимо проанализировать строку mode=append, чтобы получить значение для режима, которое быть дополнительной работой, когда вы можете просто иметь параметр с точно значением «добавить» или «перезаписать», которое необходимо извлечь. Ни один не является особым случаем, встроенным Python, не специфичным для pyspark.

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

csv(path="/path/to/file.csv", mode="append")

вместо позиционных параметров

csv("/path/to/file.csv", "append")

Это более понятно и помогает понять.

108
задан Rob Cooper 31 August 2008 в 07:35
поделиться

7 ответов

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

Foo((object)new object[]{ (object)"1", (object)"2" }));

Поскольку массив является подтипом объекта, все это работает. Бит нечетное решение, я соглашусь.

87
ответ дан Undo 21 August 2018 в 02:35
поделиться
  • 1
    то, как работают параметры, кажется ненужным, и субоптимальный дизайн c #, учитывая то, к чему мы привыкли на других языках. params можно было сделать только для принятия одной формы, и можно добавить функцию с расширением, которая принесет пользу всему языку, а не только этому случаю. например, мы могли бы заставить все вызовы параметров быть Foo (obj [0], obj [1]), а затем иметь отдельный оператор спрединга, позволяющий Foo (... obj). – Lee 15 December 2017 в 20:21
  • 2
    понял, что я не ясно дал понять, что я очень уважаю anders hejlsberg, он один из лучших языковых дизайнеров в мире. но мы можем думать об улучшениях в чьей-либо работе, учитывая достаточно оглядываясь назад, а значит, и технологии. – Lee 15 December 2017 в 20:37

Это однострочное решение, включающее LINQ.

var elements = new String[] { "1", "2", "3" };
Foo(elements.Cast<object>().ToArray())
7
ответ дан ACOMIT001 21 August 2018 в 02:35
поделиться

Модификатор параметра params дает вызывающим операторам синтаксис ярлыков для передачи нескольких аргументов методу. Существует два способа вызова метода с параметром params:

1) Вызов с массивом типа параметра, и в этом случае ключевое слово params не имеет эффекта, и массив передается напрямую к методу:

object[] array = new[] { "1", "2" };

// Foo receives the 'array' argument directly.
Foo( array );

2) Или вызов с расширенным списком аргументов, и в этом случае компилятор автоматически обернет список аргументов во временном массиве и передаст это методу:

// Foo receives a temporary array containing the list of arguments.
Foo( "1", "2" );

// This is equivalent to:
object[] temp = new[] { "1", "2" );
Foo( temp );

Чтобы передать массив объектов методу с параметром «params object[]», вы можете:

1) Создать массив обертки вручную и передать это непосредственно методу, как указано в lassevk :

Foo( new object[] { array } );  // Equivalent to calling convention 1.

2) Или, передайте аргумент object, как указано в Adam , и в этом случае компилятор создаст для вас массив-обертку:

Foo( (object)array );  // Equivalent to calling convention 2.

Однако, если целью метода является обработка нескольких объектных массивов, может быть проще объявить его с помощью явного параметра «params object[][]». Это позволит вам передать несколько массивов в качестве аргументов:

void Foo( params object[][] arrays ) {
  foreach( object[] array in arrays ) {
    // process array
  }
}

...
Foo( new[] { "1", "2" }, new[] { "3", "4" } );

// Equivalent to:
object[][] arrays = new[] {
  new[] { "1", "2" },
  new[] { "3", "4" }
};
Foo( arrays );

Изменить: Раймонд Чен описывает это поведение и как он относится к спецификации C # в новой записи .

64
ответ дан Community 21 August 2018 в 02:35
поделиться

Вам необходимо инкапсулировать его в другой массив [] []:

Foo(new Object[] { new object[]{ (object)"1", (object)"2" }});
3
ответ дан Lasse Vågsæther Karlsen 21 August 2018 в 02:35
поделиться

Один вариант - вы можете перенести его в другой массив:

Foo(new object[]{ new object[]{ (object)"1", (object)"2" } });

Вид уродливого, но поскольку каждый элемент является массивом, вы не можете просто бросить его, чтобы проблема исчезла. .. как если бы это были Foo (объекты объектов params), то вы могли бы просто сделать:

Foo((object) new object[]{ (object)"1", (object)"2" });

В качестве альтернативы вы могли бы попытаться определить другой перегруженный экземпляр Foo, который принимает только один массив:

void Foo(object[] item)
{
    // Somehow don't duplicate Foo(object[]) and
    // Foo(params object[]) without making an infinite
    // recursive call... maybe something like
    // FooImpl(params object[] items) and then this
    // could invoke it via:
    // FooImpl(new object[] { item });
}
1
ответ дан Mike Stone 21 August 2018 в 02:35
поделиться
new[] { (object) 0, (object) null, (object) false }
1
ответ дан sth 21 August 2018 в 02:35
поделиться

Другой способ решить эту проблему (это не очень хорошая практика, но выглядит красиво):

static class Helper
{
    public static object AsSingleParam(this object[] arg)
    {
       return (object)arg;
    }
}

Использование:

f(new object[] { 1, 2, 3 }.AsSingleParam());
0
ответ дан Zhuravlev A. 21 August 2018 в 02:35
поделиться
Другие вопросы по тегам:

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