Here is the output of help(str.startswith)
:
S.startswith(prefix[, start[, end]]) -> bool
Return True if S starts with the specified prefix, False otherwise.
With optional start, test S beginning at that position.
With optional end, stop comparing S at that position.
prefix can also be a tuple of strings to try.
So when you provide start and/or end, it is equivalent to
taking a slice of the string, except without needing to make a
copy first:
"Hello world".startswith("o", 4, 8)
# like "Hello world"[4:8].startswith("o")
# or "o wo".startswith("o")
Except that no actual copy of the slice needs to be made.
Then the actual startswith(“o”) comparison is equivalent to another
slice:
"o wo".startswith("o")
# equivalent to "o wo"[0:len("o") == "o"
# or "o" == "o" which is True
except, again, no actual slice is made.
If the prefix was bigger:
"Hello world".startswith("o world", 4, 8)
-> "o wo".startswith("o world")
-> "o wo"[0:7] == "o world"
-> "o wo" == "o world"
-> return False
If the prefix is smaller:
"Hello world".startswith("", 4, 8)
-> "o wo".startswith("")
-> "o wo"[0:0] == ""
-> "" == ""
-> returns True
Remember though that no actual string copies are made.
An untested pure Python implementation might be something like this:
# Warning: I have not tested this.
def startswith(string, prefix, start=0, end=None):
if end is None:
end = len(string)
if len(prefix) > end-start:
# Prefix is too long to fit in the slice.
# So it can't be a prefix of the slice.
return False
for i in range(len(prefix)):
if string[start+i] != prefix[i]:
return False
return True