list.index(x[, start[, end]])
Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item.
The optional arguments start and end are interpreted as in the slice notation and are used to limit the search to a particular subsequence of the list. The returned index is computed relative to the beginning of the full sequence rather than the start argument.
for i_row, row in enumerate(grid): # row == grid[i_row]
for i_col, value in enumerate(row): # value == row[i_col]
# далее сам
def add_time(self, h: int = 0, m: int = 0, d: int = 0, dw: int = 0, mh: int = 0, y: int = 0):
if any(v < 0 for v in [h,m,d,dw,mh,y]):
raise ValueError()
args = {'h':h, 'm':m, 'd':d, 'dw':dw, 'mh':mh, 'y':y}
bad = list(filter(lambda k: args[k] < 0, args.keys()))
if bad:
raise ValueError('Invalid values for: ' + ','.join(bad))
import functools
import inspect
# пусть чек-функция имеет вид (value) -> bool, и возвращает True для "хороших" значений. Пример:
def not_whitespace(s: str) -> bool:
'String must not contain only whitespace' # док строка будет использоваться в сообщении об ошибке
return bool(s.strip()) # проверяем что строка не состоит из одних пробелов.
# чек-функции можно генерировать и на ходу:
def in_range(low, high):
def check(value):
return (low is None or low <= value) and (high is None or value <= high)
check.__doc__ = f'Value must be between {low} and {high}.'
return check
# теперь сделаем декоратор, который умеет принимать чек-функции и применять их перед вызовом цели
def check(**checks):
def wrapper(func):
sign = inspect.signature(func)
names = list(sign.parameters.keys()) # имена параметров по порядку
not_found = set(checks.keys()) - set(names) # все ли чеки ссылаются на известные параметры?
if not_found:
# у нас есть чек на неизвестный параметр!
raise NameError(', '.join(not_found))
# всё ок, делаем обёртку над функцией
@functools.wraps(func)
def wrapped(*args, **kwargs):
bad = []
for param_name, check_func in checks.items():
idx = names.index(param_name)
if idx < len(args):
# параметр был передан через args
value = args[idx]
if not check_func(value): # вызываем чек-функцию
err = getattr(check_func, '__doc__', '')
if err:
bad.append(f'{param_name} ({err})')
else:
bad.append(param_name)
else:
pass # могут быть хитрости с kwargs-only параметрами. Тут уж извини, мне влом писать.
if bad: # нашли ошибки?
raise ValueError('Bad value for parameters: '+', '.join(bad))
# тут ещё можно помудрить над скрытием последнего фрейма в traceback, но мне опять влом
else: # не нашли, вызываем функцию
return func(*args, **kwargs)
return wrapped
return wrapper
# пример использования
# строка должна быть не из одних пробелов
# число должно быть в пределах от 1 до 10 включительно
@check(s=not_whitespace, n=in_range(1, 10))
def repeat(s: str, n: int) -> str:
return s * n
print(repeat('test ', 3))
try:
print(repeat('test ', 20))
except ValueError as err:
print('yep! it failed!', err)
try:
print(repeat('test ', -1))
except ValueError as err:
print('yep! it failed!', err)
try:
print(repeat(' ', 5))
except ValueError as err:
print('yep! it failed!', err)
try:
print(repeat(' ', 15))
except ValueError as err:
print('yep! it failed!', err)
from operator import attrgetter
sorted(items, key=attrgetter('name'))
a = [1, 2, 3] # а содержит ссылку на некий список
b = a # b содержит ссылку на тот же список!
print(b is a) # True. b - это тот же объект, что и a
a.append(4) # Ссылка а не меняется, меняется объект по этой ссылке!
print(a) # [1, 2, 3, 4]
print(b) # [1, 2, 3, 4] так как b ссылается на то же, что и a
a = [1, 2] # теперь a хранит ссылку на другой объект-список!
print(b is a) # False. Даже если бы содержимое списков совпало, это два разных объекта.
print(a) # [1, 2]
print(b) # [1, 2, 3, 4] так как b хранит ссылку на старый список
a.append(5)
print(a) # [1, 2, 5] изменили объект, на который ссылается a
print(b) # [1, 2, 3, 4] b ссылается на другой объект, он остался не изменён.
a[:] = [1, 2, 3, 4]
Для надёжности можешь этот список показать как read-only property вместо обычного поля класса - тогда можно будет модифицировать объект списка (добавлять/удалять элементы), но нельзя будет заменить список на другой.item.open_items = ['item 1', 'item 2']
item.open_items.append('item 1')
Как вывести первый ключ из словаря?
Как вывести только 'Pomidorka' из словаря?
list(users.keys()) # ['Ivan', 'Anton', 'Pomidorka', 'Ananas']
list(users.keys())[0]
list(users.keys())[2]
Person.__dict__
setattr(Person, 'name', 'value')
delattr(Person, 'name',)
p = Person(*attr)
len(p)
class Person:
.......
def __len__(self):
return x
if bbb:
property
- как раз для этого случая они подходят на 100%. Но придется написать много кода.class Person:
has_map = {True: 'Есть', False: 'Нет'}
def __init__(self, name):
self.name = name
self._something_1 = False
self._something_2 = True
@property
def something_1(self):
return self.has_map[self._something_1]
@something_1.setter
def something_1(self, value):
self._something_1 = value
@property
def something_2(self):
return self.has_map[self._something_2]
@something_2.setter
def something_2(self, value):
self._something_2 = value
def attr_mapping(value):
has_map = {True: 'Есть', False: 'Нет'}
if isinstance(value, bool):
return has_map[value]
if __name__ == '__main__':
Anna = Person('Anna')
print(Anna.something_2)
Anna.something_2 = False
print(Anna.something_2)
Anna = Person('Anna')
print(attr_mapping(Anna._something_2))
Anna._something_2 = False
print(attr_mapping(Anna._something_2))
class Person:
def __init__(self, name):
self.name = name
self.something_1 = 'abc'
self.something_2 = 123
def check_attr(obj, attr_name):
try:
value = obj.__getattribute__(attr_name)
return f'{obj} имеет аттрибут - {attr_name} со значением - {value}'
except AttributeError:
return f'{obj} не имеет аттрибута - {attr_name}'
if __name__ == "__main__":
p = Person(name='Alex')
print(check_attr(p, 'something_1'))
print(check_attr(p, 'something_2'))
print(check_attr(p, 'something_33333'))
class BaseField:
def __init__(self, value):
self.value = value
def __eq__(self, other):
if isinstance(other, BaseField):
return self.value == other.value
return self.value == other
def __repr__(self):
return str(self.value)
class BoolField(BaseField):
def __str__(self):
return {
True: 'Есть',
False: 'Нет'
}.get(self.value)
class MoneyField(BaseField):
def __str__(self):
return f'{self.value}$'
class Person:
def __init__(self, name):
self.name = name
self.something_1 = BoolField(False)
self.something_2 = BoolField(True)
self.money = MoneyField(1500)
p = Person('Vladimir')
print(p.something_1)
print(p.money)