Этот ответ витает в нескольких местах. Использование DataGridViewEditingControlShowingEventHandler вызовет больше событий, чем вы намереваетесь. В моем тестировании это вызвало событие несколько раз. Также использование события combo.SelectedIndexChanged - = на самом деле не удалит событие, а просто продолжит укладку. Во всяком случае, я нашел решение, которое, кажется, работает. Я включаю пример кода ниже:
// Add the events to listen for
dataGridView1.CellValueChanged +=
new DataGridViewCellEventHandler(dataGridView1_CellValueChanged);
dataGridView1.CurrentCellDirtyStateChanged +=
new EventHandler(dataGridView1_CurrentCellDirtyStateChanged);
// This event handler manually raises the CellValueChanged event
// by calling the CommitEdit method.
void dataGridView1_CurrentCellDirtyStateChanged(object sender,
EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
// This fires the cell value changed handler below
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// My combobox column is the second one so I hard coded a 1, flavor to taste
DataGridViewComboBoxCell cb = (DataGridViewComboBoxCell)dataGridView1.Rows[e.RowIndex].Cells[1];
if (cb.Value != null)
{
// do stuff
dataGridView1.Invalidate();
}
}
Посмотрите на PyChecker и PyLint .
Вот пример вывода pylint, полученный из тривиальной программы:
print a
Как вы можете видеть , он обнаруживает неопределенную переменную, которую py_compile не будет (намеренно).
in foo.py:
************* Module foo
C: 1: Black listed name "foo"
C: 1: Missing docstring
E: 1: Undefined variable 'a'
...
|error |1 |1 |= |
Тривиальный пример того, почему тесты недостаточно хороши, даже если они охватывают «каждую строку»:
bar = "Foo"
foo = "Bar"
def baz(X):
return bar if X else fo0
print baz(input("True or False: "))
РЕДАКТИРОВАТЬ: PyChecker обрабатывает троичную систему за меня :
Processing ternary...
True or False: True
Foo
Warnings...
ternary.py:6: No global (fo0) found
ternary.py:8: Using input() is a security problem, consider using raw_input()
Я думаю, что вы ищете Покрытие тестовой строки кода. Вы хотите добавить в свой скрипт тесты, которые обеспечат тестирование всех ваших строк кода или столько, сколько у вас есть времени. Тестирование - это большая работа, но если вы хотите получить такую уверенность, то бесплатного обеда нет, извините :(.
Если вы используете Eclipse с Pydev в качестве среды IDE, она может сразу же отмечать многие опечатки красными волнистыми линиями, а также имеет интеграцию с Pylint. Например:
foo = 5
print food
будет помечен как «Неопределенная переменная: еда». Конечно, это не всегда точно (возможно, еда была определена ранее с помощью setattr или других экзотических методов), но в большинстве случаев он работает хорошо.
В общем, вы можете статически анализировать свой код только в той степени, в которой ваш код фактически статичный; чем более динамичен ваш код, тем больше вам действительно нужно автоматическое тестирование.
Ваш код фактически компилируется, когда вы его запускаете, среда выполнения Python пожалуется, если в коде есть синтаксическая ошибка. По сравнению со статически скомпилированными языками, такими как C / C ++ или Java, он не проверяет правильность имен и типов переменных - для этого вам нужно фактически запустить код (например, с помощью автоматических тестов).
Другие упоминали такие инструменты, как PyLint, которые довольно хороши, но долгие и Короче говоря, сделать 100% просто невозможно. На самом деле, возможно, вы даже не захотите этого делать. Одним из преимуществ динамичности Python является то, что вы можете делать сумасшедшие вещи, например вставлять имена в локальную область видимости через доступ к словарю.
Все сводится к тому, что если вам нужен способ отлова ошибок типа во время компиляции, вы не следует использовать Python. Выбор языка всегда требует компромиссов. Если вы выберете Python вместо C, просто помните, что вы торгуете сильной системой типов для более быстрой разработки, лучшего манипулирования строками и т.д.
но короче и длинною в том, что сделать все на 100% просто невозможно. На самом деле, возможно, вы даже не захотите этого делать. Отчасти преимущество динамичности Python заключается в том, что вы можете делать сумасшедшие вещи, например вставлять имена в локальную область видимости через доступ к словарю.Все сводится к тому, что если вам нужен способ отлова ошибок типа во время компиляции, вы не следует использовать Python. Выбор языка всегда требует компромиссов. Если вы выберете Python вместо C, просто помните, что вы торгуете сильной системой типов для более быстрой разработки, лучшего манипулирования строками и т. Д.
но короче и длинною в том, что сделать все на 100% просто невозможно. На самом деле, возможно, вы даже не захотите этого делать. Отчасти преимущество динамичности Python заключается в том, что вы можете делать сумасшедшие вещи, например вставлять имена в локальную область видимости через доступ к словарю.Все сводится к тому, что если вам нужен способ отлова ошибок типа во время компиляции, вы не следует использовать Python. Выбор языка всегда требует компромиссов. Если вы выберете Python вместо C, просто помните, что вы торгуете сильной системой типов для более быстрой разработки, лучшего манипулирования строками и т. Д.
Все сводится к тому, что если вам нужен способ отлова ошибок типа во время компиляции, вам не следует использовать Python. Выбор языка всегда требует компромиссов. Если вы выберете Python вместо C, просто помните, что вы торгуете сильной системой типов для более быстрой разработки, лучшего манипулирования строками и т. Д.
Все сводится к тому, что если вам нужен способ отлова ошибок типа во время компиляции, вам не следует использовать Python. Выбор языка всегда требует компромиссов. Если вы выберете Python вместо C, просто помните, что вы торгуете сильной системой типов для более быстрой разработки, лучшего манипулирования строками и т. Д.