Функции grid
, pack
и place
объекта Entry
и всех других виджетов возвращают None
. В python, когда вы делаете a().b()
, результат выражения - это то, что возвращает b()
, поэтому Entry(...).grid(...)
вернет None
.
Вы должны разделить это на две строки следующим образом:
entryBox = Entry(root, width=60)
entryBox.grid(row=2, column=1, sticky=W)
Таким образом вы получите свою Entry
ссылку, сохраненную в entryBox
, и она выложена, как вы ожидаете. Это имеет бонусный побочный эффект, заключающийся в том, что ваш макет легче понять и поддерживать, если вы собираете все свои grid
и / или pack
операторы в блоках.
В Scala есть хорошая поддержка псевдонимов типов. Например:
type FooBBQ = Foo[Bar[Baz,Qux]]
Я понимаю, что этот ответ не будет полезным, если у вас нет возможности переключиться на Scala. Но если у вас есть возможность переключения, вам может быть легче.
Я бы сказал, что да, вам нужно переосмыслить проблему. Объявление
class DoableImpl implements Doable<Foo<Bar<Baz,Qux>>,Foo<Bar<Zot,Qux>>> {
Foo<Bar<Baz,Qux>> doIt(Foo<Bar<Zot,Qux>> fooBZQ) { ... }
}
является довольно очевидным случаем чрезмерного использования дженериков.
Ну, у Java нет псевдонимов типов, так что вам не повезло. Однако псевдонимы типов иногда можно заменить переменными типов! Таким образом, мы решаем проблему слишком большого числа обобщений с помощью еще большего количества обобщений!
Поскольку вы удалили весь контент из вашего примера, я не могу догадаться, где или имеет ли смысл вводить дополнительные переменные типа, но здесь одно возможное разложение:
class DoableImplFoo<A,B> implements Doable<Foo<A>,Foo<B>> {
public DoableImplFoo(SomePropertyOf<A,B> aAndBAreGoodEnough) { ... }
Foo<A> doIt(Foo<B> fooB) { ... }
}
Когда вы создаете экземпляры A
до Bar<Baz,Qux>
и B
до Bar<Zot,Qux>
позже, вы можете обнаружить, что снова есть какой-то шаблон, но он может быть меньше, чем вы Первоначально был.
Может быть, иметь столько общих параметров, это просто плохая идея, и мне нужно переосмыслить проблему?
Очень вероятно. Нужно ли специализировать Doit в 8 измерениях?
Во многих случаях эти типы не существуют в вакууме, и вам следует подумать, какие доменные объекты представляет ваша «обертка», а не использовать их как удобство кодирования.
Если Вы хотите полную безопасность типов, я не думаю, что можно добиться большего успеха без некоторых классов обертки. Но, почему бы не заставить те классы наследоваться/реализовать исходные универсальные версии, как это:
public class FooBBQ extends Foo<Bar<Baz,Qux>> {
...
}
Это избавляет от необходимости toGeneric()
метод, и более ясно, по-моему, что это - просто псевдоним типа. Кроме того, универсальный тип может быть брошен в FooBBQ
без предупреждения компилятора. Это было бы мое персональное предпочтение для создания Foo, Bar, Baz...
интерфейсы, бы, если это возможно, даже если некоторое дублирование кода произошло бы в реализации.
Теперь, не зная конкретной проблемной области, трудно сказать, нуждаетесь ли Вы, говорите FooBBQ
, как в Вашем примере, или возможно a:
public class FooBar<X, Y> extends Foo<Bar<X, Y>> {
...
}
С другой стороны, Вы думали о простом конфигурировании компилятора Java не показывать некоторые универсальные предупреждения и просто опускать части универсального определения? Или, используйте стратегически помещенный @SuppressWarnings("unchecked")
? Другими словами, можете Вы делать DoableImpl
только "частично genericized":
class DoableImpl implements Doable<Foo<Bar>>,Foo<Bar>> {
Foo<Bar> doIt(Foo<Bar> foobar) { ... }
}
и проигнорируйте предупреждения ради меньшей помехи кода? Снова, трудно для решения без конкретного примера но это - еще одна вещь, которую можно попробовать.