Last active
September 17, 2021 15:12
-
-
Save IgorZyktin/87cbbb99da34990a89301a328fc5fc50 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import UserString | |
from typing import Union | |
class StrIns(UserString): | |
def __setitem__(self, key: Union[int, slice], value: str) -> None: | |
if isinstance(key, int): | |
self._assign_one_element(key, value) | |
elif isinstance(key, slice): | |
self._assign_slice(key, value) | |
else: | |
type_name = type(key).__name__ | |
raise TypeError(f'Setitem does not support type {type_name}') | |
def _assign_one_element(self, index: int, value: str) -> None: | |
if not isinstance(value, str): | |
type_name = type(value).__name__ | |
raise TypeError('Assignment works with ' | |
f'strings only, got {type_name}') | |
if len(value) != 1: | |
raise ValueError('Index assignment works ' | |
f'with single character only, got {value!r}') | |
self.data = self.data[:index] + value + self.data[index + 1:] | |
def _assign_slice(self, index: slice, value: str) -> None: | |
if index.start is None: | |
index.start = 0 | |
if index.stop is None: | |
index.stop = len(self.data) | |
index = slice(index.start, index.stop, index.step or 1) | |
if index.step == 1: | |
self._assign_slice_simple(index, value) | |
else: | |
self._assign_slice_complex(index, value) | |
def _assign_slice_simple(self, index: slice, value: str) -> None: | |
self.data = (self.data[:index.start] | |
+ value + self.data[index.stop + 1:]) | |
def _assign_slice_complex(self, index: slice, value: str) -> None: | |
as_list = list(self.data) | |
as_list[index] = list(value) | |
self.data = ''.join(as_list) | |
var = StrIns('some string') | |
print('Original:', var) # Original: some string | |
print('Indexing:', var[0]) # Indexing: s | |
var[0] = '1' | |
var[1] = '2' | |
print('After assignment:', var) # After assignment: 12me string | |
print('Find:', var.find('m')) # Find: 2 | |
var[0:3] = 'some other long' | |
print('Slice assignment simple:', var) # Slice assignment simple: some other long string | |
var[21:4:-2] = 'something' | |
print('Slice assignment complex:', var) # Slice assignment complex: some gtnei hotgesmrons |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment