mmap модуль Python позволит Вам вставлять в файл. Следующий образец показывает, как он может быть сделан в Unix (Windows mmap может отличаться). Обратите внимание, что это не обрабатывает все состояния ошибки, и Вы могли бы повредить или потерять исходный файл. Кроме того, это не обработает строки unicode.
import os
from mmap import mmap
def insert(filename, str, pos):
if len(str) < 1:
# nothing to insert
return
f = open(filename, 'r+')
m = mmap(f.fileno(), os.path.getsize(filename))
origSize = m.size()
# or this could be an error
if pos > origSize:
pos = origSize
elif pos < 0:
pos = 0
m.resize(origSize + len(str))
m[pos+len(str):] = m[pos:origSize]
m[pos:pos+len(str)] = str
m.close()
f.close()
также возможно сделать это без mmap с файлами, открытыми в 'r +' режим, но это менее удобно и менее эффективно, поскольку необходимо было бы считать и временно сохранить содержание файла от положения вставки до EOF - который мог бы быть огромным.
Я немного подумал над этим вопросом и после небольшого размышления согласен с тем, что реализация IEquatable
и IComparable
должна выполняться только на запечатанные типы.
Я немного ходил туда-сюда, но потом подумал о следующем тесте. При каких обстоятельствах следующее должно возвращать false? ИМХО, 2 объекта либо равны, либо нет.
public void EqualitySanityCheck<T>(T left, T right) where T : IEquatable<T> {
var equals1 = left.Equals(right);
var equals2 = ((IEqutable<T>)left).Equals(right);
Assert.AreEqual(equals1,equals2);
}
Результат IEquatable
для данного объекта должен иметь то же поведение, что и Object.Equals
, при условии, что компаратор имеет эквивалентный тип. Двойная реализация IEquatable
в иерархии объектов позволяет и подразумевает, что существует 2 различных способа выражения равенства в вашей системе. Это' Легко придумать любое количество сценариев, в которых IEquatable
и Object.Equals
будут различаться, поскольку существует несколько IEquatable
реализаций, но только одна Object.Equals
. Следовательно, приведенное выше приведет к ошибке и создаст некоторую путаницу в вашем коде.
Некоторые люди могут возразить, что реализация IEquatable
на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer
, который специально разработан для сравнения этих свойств.
Object.Equals
. Следовательно, приведенное выше приведет к ошибке и создаст некоторую путаницу в вашем коде.
Некоторые люди могут возразить, что реализация IEquatable
на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer
, который специально разработан для сравнения этих свойств.
Object.Equals
. Следовательно, приведенное выше приведет к ошибке и вызовет некоторую путаницу в вашем коде.
Некоторые люди могут возразить, что реализация IEquatable
на более высоком уровне иерархии объектов допустима, потому что вы хотите сравнить подмножество свойств объектов. В этом случае вам следует отдать предпочтение IEqualityComparer
, который специально разработан для сравнения этих свойств.
Большинство реализаций Equals
, которые я видел, проверяют типы сравниваемых объектов, если они не совпадают, метод возвращает false.
Это аккуратно. позволяет избежать проблемы сравнения подтипа с его родительским типом, тем самым устраняя необходимость герметизации класса.
Очевидным примером этого может быть попытка сравнения двухмерной точки (A) с трехмерной точкой (B). : для 2D значения x и y 3D-точки могут быть равны, но для 3D-точки значение z, скорее всего, будет другим.
Это означает, что A == B
будет правда, но B == A
будет ложью. Большинству людей нравится, что операторы Equals
являются коммутативными, в этом случае проверка типов явно является хорошей идеей.
Но что, если вы создаете подклассы, а не не добавить новые свойства? Что ж, на этот вопрос ответить немного сложнее и, возможно, зависит от вашей ситуации.