TypeError: получен неожиданный аргумент ключевого слова - объектно-ориентированное программирование [дубликат]

Ошибка - исправлено в Java 9

Эта проблема уже сообщалась в JDK-bug-log . Стивен Коулборн упоминает следующее решение:

DateTimeFormatter dtf = 
  new DateTimeFormatterBuilder()
  .appendPattern("yyyyMMddHHmmss")
  .appendValue(ChronoField.MILLI_OF_SECOND, 3)
  .toFormatter();

Примечание. Это обходное решение не охватывает ваш случай использования только двух символов шаблона SS. Настройкой может быть только использование других полей, таких как MICRO_OF_SECOND (6 раз SSSSSS) или NANO_OF_SECOND (9 раз SSSSSSSSS).

@PeterLawrey О значении символа шаблона «S» см. эту документацию :

Фракция: Выводит поле nano-of-second как долю секунды. Значение nano-of-second имеет девять цифр, поэтому количество букв шаблона составляет от 1 до 9. Если оно меньше 9, то значение nano-of-second усекается, и выводятся только самые значащие цифры. При синтаксическом анализе в строгом режиме количество проанализированных цифр должно соответствовать количеству букв шаблонов. При разборе в режиме смягчения количество проанализированных цифр должно быть не менее, чем число букв шаблонов, до 9 цифр.

blockquote>

Таким образом, мы видим, что S обозначает любую долю секунды (в том числе наносекунды), а не только миллисекунды. К сожалению, дробная часть в данный момент не очень хорошо воспринимается при смежном разборе значений.

EDIT:

В качестве фона здесь приведены некоторые замечания о смежном анализе значений. До тех пор, пока поля разделяются литералами, такими как десятичные точки или разделители временной части (двоеточие), интерпретация полей в анализируемом тексте не является сложной задачей, потому что синтаксический анализатор тогда легко знает, когда останавливаться, т.е. когда часть поля заканчивается и когда начинается следующее поле. Поэтому парсер JSR-310 может обрабатывать текстовую последовательность, если вы указываете десятичную точку.

Но если у вас есть последовательность смежных цифр, охватывающих несколько полей, возникают некоторые трудности с реализацией. Чтобы позволить парсеру знать, когда поле останавливается в тексте, необходимо заранее проинструктировать парсер, что данное поле представлено фиксированной шириной символов цифр. Это работает со всеми appendValue(...) -методами, которые принимают численные представления.

К сожалению, JSR-310 не сумел сделать это также с дробной частью (appendFraction(...)). Если вы ищете ключевое слово «смежное» в javadoc класса DateTimeFormatterBuilder, вы обнаружите, что эта функция ТОЛЬКО реализована с помощью методов appendValue(...). Обратите внимание, что спецификация для буквы шаблона S немного отличается, но внутренне делегирует appendFraction() -метод. Я предполагаю, что мы, по крайней мере, должны будем связываться до Java 9 (как сообщается в JDK-журнале ошибок или позже) до тех пор, пока фракционные части не смогут управлять парсингами смежных значений.


Update от 2015-11-25:

Следующий код с использованием двух цифр разряда не работает и выдает DateTimeParseException.

DateTimeFormatter dtf = 
  new DateTimeFormatterBuilder()
  .appendPattern("yyyyMMddHHmmssSS")
  .appendValue(ChronoField.MILLI_OF_SECOND, 2)
  .toFormatter();
String input = "2011120312345655"; 
LocalDateTime.parse(input, dtf); // abort

Обходной путь

String input = "2011120312345655"; 
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
Date d = sdf.parse(input);
System.out.println(d.toInstant()); // 2011-12-03T12:34:56.055Z

не работает, потому что SimpleDateFormat неправильно интерпретирует дробь (см. вывод, 55 мс вместо 550 мс).

То, что остается в качестве решения, либо ждет долгое время, дольше, чем Java 9 (или позже?), либо записывает ваш собственный взлом или использует сторонние библиотеки в качестве решения.

Решение на основе грязного взлома:

String input = "2011120312345655"; 
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
int len = input.length();
LocalDateTime ldt = LocalDateTime.parse(input.substring(0, len - 2),  dtf);
int millis = Integer.parseInt(input.substring(len - 2)) * 10;
ldt = ldt.plus(millis, ChronoUnit.MILLIS);
System.out.println(ldt); // 2011-12-03T12:34:56.550

Решение с использованием Joda-Time :

String input = "2011120312345655"; 
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyyMMddHHmmssSS");
System.out.println(dtf.parseLocalDateTime(input)); // 2011-12-03T12:34:56.550

Решение с использованием моего библиотека Time4J :

String input = "2011120312345655"; 
ChronoFormatter f = 
  ChronoFormatter.ofTimestampPattern("yyyyMMddHHmmssSS", PatternType.CLDR, Locale.ROOT);
System.out.println(f.parse(input)); // 2011-12-03T12:34:56.550

Обновление от 2016-04-29:

Как люди могут видеть по упомянутой выше проблеме JDK, теперь он помечен как разрешенный - для Java 9.

24
задан kramer65 31 May 2013 в 11:45
поделиться

2 ответа

Для вопроса 2 вам нужно вызвать super в каждом классе:

class First(object):
    def __init__(self):
        super(First, self).__init__()
        print "first"

class Second(object):
    def __init__(self):
        super(Second, self).__init__()
        print "second"

class Third(First, Second):
    def __init__(self):
        super(Third, self).__init__()
        print "that's it"

Для вопроса 3 это невозможно сделать, ваш метод должен иметь одну и ту же подпись. Но вы можете просто игнорировать некоторые параметры в родительских кланах или использовать аргументы ключевых слов.

11
ответ дан Guillaume 19 August 2018 в 17:31
поделиться
  • 1
    Итак, вы подразумеваете, что использование super () зависит от использования super () в унаследованных классах? Что делать, если я не контролирую унаследованные классы? Разве я тогда просто сделаю First .__ init __ (self) и Second .__ init __ (self), как в моем первом примере? – kramer65 31 May 2013 в 12:08
  • 2
    Да, "супер" является совместным процессом, все классы должны использовать механизм или он просто не работает. Вы можете найти немного больше информации здесь: rhettinger.wordpress.com/2011/05/26/super-considered-super И да, если класс в иерархии не использует супер, я думаю вы должны использовать «старый стиль». путь :) – Guillaume 31 May 2013 в 12:13
  • 3
    Спасибо за это. Только один последний вопрос; почему super () добавлен на язык в любом случае? В чем преимущество этого «старых стилей»? – kramer65 31 May 2013 в 14:37
  • 4
    Я вижу два преимущества: вам не нужно явно ссылаться на родительский класс, и в случае множественного наследования вам не нужно вызывать несколько родительских конструкторов ... также в python3, вам нужно только вызвать super (). Something ( ) вместо super (Class, self) .something () – Guillaume 31 May 2013 в 14:46
  • 5
    Вы говорите: «в случае множественного наследования вам не нужно вызывать несколько родительских конструкторов». Я не понимаю этого, потому что, если я вызову super (CurrentClass, self) .__ init __ () (как и в моем втором фрагменте кода), он запускает только функцию init первого унаследованного класса вместо init all унаследованные классы. Таким образом, это означает, что super () не может использоваться при выполнении множественного наследования .. правильно? – kramer65 31 May 2013 в 19:01

1) Нет ничего плохого в том, что вы сделали в 1, если вы хотите использовать атрибуты из базового класса, тогда вам нужно вызвать базовый класс init () или даже если ur использует методы из базового класса, которые использует атрибуты своего собственного класса, тогда вам нужно вызвать baseclass init ()

2) Вы не можете использовать super для запуска init с First и Second, потому что python использует MRO (порядок разрешения метода)

см. следующий код: это иерархия алмазов

class A(object): 
    def __init__(self):
        self.a = 'a'
        print self.a

class B(A):
    def __init__(self):
        self.b = 'b'
        print self.b

class C(A):
    def __init__(self):
        self.c = 'c'
        print self.c

class D(B,C):
    def __init__(self):
        self.d = 'd'
        print self.d
        super(D, self).__init__()

d = D()
print D.mro()

Он печатает:

d
b
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <type 'object'>]

MRO питона будет D, B, C, A

, если у B нет метода init для C.

3) Вы не можете использовать все методы, чтобы иметь такую ​​же подпись.

2
ответ дан radtek 19 August 2018 в 17:31
поделиться
Другие вопросы по тегам:

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