Аргументи, грешки и статични методи

Какво е positional(позиционен) аргумент?

  • Стандарните аргументи, които сме разглеждали до сега са позиционни

  • Те зависят от позоцията и са задължителни

def sum(a, b):
    return a+b

sum(2, 3)

Пример

Има начини функциите да приемат променлив брой positional аргументи.

Как става това?

*args

def test_var_args(*args):
    for arg in args:
        print("arg:{}".format(arg))


Списък от аргументи -като positional аргументи

>>> test_var_agrs(1, "two", 3)

arg: 1
arg: two
arg: 3

*args

def test_var_args(farg, *args):
    print("formal arg:{}".format(farg))
    for arg in args:
        print("another arg:{}".format(arg))

Списък от аргументи -като positional аргументи

>>> test_var_agrs(1, "two", 3)

formal arg: 1
another arg: two
another arg: 3

Освен това, имаме друг вид аргументи - keyword, които ни позволяват да дефинираме default-ни стойности на аргументите.

  • Редът на подаване няма значение!

  • На принципа kwarg=valuе

  • Чрез default-ните аргументи не задължаваме потребителя всеки път да ги въвежда

  • При извикването на функцията  default-ните стойностти могат да бъдат променяни

Разлики между positional и keyword аргументи

Keyword Arguments

def tomato(weigth, color='red'):
    print("Tomato - {}gr".format(weigth))
    print("And it is colored {}".format(color))

tomato(20)                       # 1 positional argument
tomato(weigth=1000)              # 1 keyword argument
ttomato(10, color='pink')        # 1 positional argument, 1 keyword
tomato(weigth=25, color='yellow')# 2 keyword arguments
Tomato - 20gr
And it is colored red

Tomato - 1000gr
And it is colored red

Tomato - 10gr
And it is colored pink

Tomato - 25gr
And it is colored yellow

>>> tomato(20)
>>> tomato(weigth=1000)
>>> tomato(10, color='pink')
>>> tomato(weigth=25, color='yellow')

Какъв е резултата от изпълнението на всяко извикване?

>>> tomato()
>>> tomato(color='pink')
>>> tomato(20, 'black')
>>> tomato(weigth=10, 'blue')
    tomato()
TypeError: tomato() missing 1 required positional argument: 'weigth'

    tomato(color='pink')
TypeError: tomato() missing 1 required positional argument: 'weigth'

tomato(20,'black')
Tomato - 20gr
And it is colored black

    tomato(weigth=10,'blue')
                    ^
SyntaxError: non-keyword arg after keyword arg



Какъв е резултата от изпълнението на всяко извикване?

Има начини функциите да приемат променлив брой keyword аргументи.

Как става това?

**kwargs

def test_var_kwargs(farg, **kwargs):
    print("formal arg:{}".format(farg))
    for key in kwargs:
        print ("another keyword arg: {}: {}".format(key, kwargs[key]))

Речник от аргументи -като keyword аргументи


>>> test_var_kwargs(farg=1, myarg2="two", myarg3=3)

formal arg:1
another keyword arg: myarg3: 3
another keyword arg: myarg2: two

И всички видове аргументи заедно...

*args и **kwargs

def cheeseshop(kind, *args, **kwargs):
    print("-- Do you have any {}".format(kind))

    for arg in args:
        print(arg)

    print("-"*40)

    for key in kwargs:
        print("{}:{}".format(key, kwargs[key]))


cheeseshop("Limburger", "It's very runny, sir.", "It's really VERY runny",
shopkeeper="Michael", client="John", sketch="Cheese Shop Sketch")
>>> cheeseshop("Limburger", "It's very runny, sir.","It's really VERY runny",
shopkeeper="Michael", client="John", sketch="Cheese Shop Sketch")


-- Do you have any Limburger
It's very runny, sir.
It's really VERY runny
----------------------------------------
sketch:Cheese Shop Sketch
shopkeeper:Michael
client:John

Exceptions

>>> 10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

Примери за грешки

Как да "хващаме" Exceptions?

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")

Чрез конструкцията "try-except".

Please enter a number:ks
Oops!  That was no valid number.  Try again...

Как работи "try-except"?

  • първо се изпълнява try клаузата
  • ако не възникне изключение, се изпълнява целия блок
  • ако възникне изключение, изпълнението на try блока спира и се проверява дали това изключение го има в някой от except блоковете
  • ако го има, то се изпълнява неговия блок
  • ако го няма , търси нагоре във функциите и ако отново не намери, такава,която да го хваща - спира изпълнението и хвърля грешката
def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("division by zero!")
    except TypeError:
        print("Invalid type argument!")
    else:
        print("Result is {}".format(result))

divide(5, 0)
divide(5,2)
divide("5",0)
Division by zero!
Result is 2.5
Invalid type argument!

Какво ще се изведе след изпълнение?

А можете и да "хвърляте" грешки..

class Rectangle:

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if width == 0 and height == 0:
            raise ValueError("sorry, you lose")

        if color == 'blue':
            raise Exception("Ooo it's blue!")

        self.width = width
        self.height = height


rec = Rectangle(0, 0, color='red', emphasis='strong', highlight=50)

rec1 = Rectangle(5, 10, color='blue')

rec2 = Rectangle(10,color='blue')

raise Exception

rec = Rectangle(0, 0, color='red', emphasis='strong', highlight=50)


rec1 = Rectangle(5, 10, color='blue')


rec2 = Rectangle(10,color='blue')

ValueError: sorry, you lose

Exception: Ooo it's blue!"

TypeError: __init__() missing 1 required positional argument: 'height'

Кога използваме статични методи?

Как викаме статични методи?

  • през КЛАС

class Dungeon:

    @staticmethod
    def create_from_file(path):
        dungeon = []
        with open(path, "r") as f:
            contents = f.read().split("\n")
            dungeon = [list(line) for line in contents if line.strip() != ""]

        return Dungeon(dungeon)



dungeon = Dungeon.create_from_file(/../..)

Приложение:

deck

By Hack Bulgaria

deck

  • 1,418