Расширение ответа @ Kiran, которое я согласен, более кратким и Pythonic, это добавляет кодеки для поддержки чтения и записи UTF-8:
import codecs
from tempfile import mkstemp
from shutil import move
from os import remove
def replace(source_file_path, pattern, substring):
fh, target_file_path = mkstemp()
with codecs.open(target_file_path, 'w', 'utf-8') as target_file:
with codecs.open(source_file_path, 'r', 'utf-8') as source_file:
for line in source_file:
target_file.write(line.replace(pattern, substring))
remove(source_file_path)
move(target_file_path, source_file_path)
Мои правила:
null
, false
, 0
, 0.0
†¦). В C# это не имеет значения. Эти два примера кода, которые Вы даете, совершенно эквивалентны. В первом примере компилятор C# (или действительно ли это - CLR?) создаст пустого конструктора и инициализирует переменные, как будто они были в конструкторе (существует небольшой нюанс к этому, который Jon Skeet объясняет в комментариях ниже). Если уже будет конструктор тогда, то любая инициализация "выше" будет перемещена в вершину его.
С точки зрения лучшей практики первый менее подвержен ошибкам, чем последний, как кто-то мог легко добавить другого конструктора и забыть объединять ее в цепочку.
Семантика C# отличается немного от Java здесь. В присвоении C# в объявлении выполняется прежде, чем назвать конструктора суперкласса. В Java это сразу сделано, после которого позволяет 'этому' использоваться (особенно полезный для анонимных внутренних классов) и означает, что семантика двух форм действительно соответствует.
, Если Вы можете, сделайте полевой финал.
Принятие типа в Вашем примере, определенно предпочтите инициализировать поля в конструкторе. Исключительные случаи:
, я всегда думаю о списке полей наверху класса как оглавление (что содержится здесь, не, как это используется), и конструктор как введение. Методы, конечно, являются главами.
Что, если я сказал Вам, это зависит?
я в целом инициализирую все и делаю это последовательным способом. Да это чрезмерно явно, но также немного легче поддержать.
, Если мы волнуемся по поводу производительности, хорошо тогда, я инициализирую только, что должно быть сделано и поместить ее в области, которые она дает большей части удара для маркера.
В системе реального времени, я подвергаю сомнению, нужны ли мне даже переменное или постоянное вообще.
И в C++ я часто не делаю рядом ни с какой инициализацией ни в одном месте и перемещаю его в Init () функция. Почему? Ну, в C++, если Вы инициализируете что-то, что может выдать исключение во время объектной конструкции, которую Вы открываете сами для утечек памяти.
Я обычно сужу конструктора, чтобы сделать только получение зависимостей и инициализацию связанных членов экземпляра с ними. Это сделает Вас жизнью легче, если Вы захотите к модульному тесту свои классы.
, Если значение Вы собираетесь присвоить переменной экземпляра, не добирается под влиянием ни одного из параметров, которые Вы собираетесь передать Вам, конструктор тогда присваивает его во время объявления.
Существует небольшой выигрыш в производительности к устанавливанию значения в объявлении. При установке его в конструкторе, это на самом деле устанавливается дважды (сначала к значению по умолчанию, то сброшенный в ctor).