Лучше так пиши
>>> def get_hidden_card(card_number, stars_count=4):
... visible_digits_line = card_number[-4:]
... return '*' * stars_count + visible_digits_line
...
>>> get_hidden_card('1234123412341234')
'****1234'
>>>
Чем проще, тем лучше.
Kvit
При перемножении строки на число, разве, не должно выдавать ошибку? Или это только сложения/вычитания касается? Или это только в f-строках работает?
У питона строгая и динамическая типизация. Просто для этих конкретных типов предусмотрены такие конкретные операции некоторые. Например, строку можно умножить на число, но нельзя умножить на строку. Также строку нельзя поделить вообще на что-то.
>>> 'a' * 3
'aaa'
>>> 'a' * 'b'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
>>> 'a' / 3
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for /: 'str' and 'int'
>>>
Есть правило такое, что “тип <строка> нельзя умножить на тип <строка>”. В существовании такого правила и заключается строгость. В языках со слабой типизацией таких правил нет, поэтому там просто что-то получается в любом случае.
А динамичность типизации - это когда мы код написали но не знаем, какой тип будет под таким-то именем, когда программа запустится и дойдёт до этого имени.
>>> import time
>>>
>>> if time.time() % 10 > 5:
... a = 1
... else:
... a = 'text'
...
>>> a
1
>>>
>>> import time
>>>
>>> if time.time() % 10 > 5:
... a = 1
... else:
... a = 'text'
...
>>> a
'text'
>>>
В языках со статической типизацией после написания кода уже точно известно где и какие типы будут под всеми именами, ещё до первого запуска программы.
Типизация бывает строгая и статическая, а бывает слабая и динамическая.
Типизация бывает слабая и статическая, а бывает строгая и динамическая.