Python深化:function parameter

16763 ワード

function parameter
Argument vs Parameter
Semantics
parameter
함수 정의 시 parameter라고 부름
def my_func(a, b):
    pass
arguments
  • 関数を呼び出すときはパラメータ
  • と呼ぶ.
    x = 1
    y = "a"
    my_func(x, y)
  • の場合、x,yはreference関数に参照(アドレス値)を渡す.
  • Positional and Keyword Arguments
  • 関数を定義または呼び出した場合、kwagsが表示された場合は、後でkwagsである必要があります.
  • defmy func(a=1,b,c)は不可能!
  • my func(a=1,2,3)は不可能!
  • Unpacking Iterables
    tupleの定義方法
  • カッコ()を使うのもtupleですが、下のようにtupleです.
  • a = 1,2,3
    print(a)
    print(type(a))
    (1, 2, 3)
    <class 'tuple'>
    Packed Values
    縛られた価値観を指す.
  • list、tuple、str、set、dictはいずれも包装値である.
  • in fact, any iterable can be considered a packed value
  • Unpacking Packed Values
    a,b,c = [1,2,3]
    print(a,b,c)
    a,b,c = 10, 20, "hello"
    print(a,b,c)
    a,b,c = "XYZ"
    print(a,b,c)
    
    1 2 3
    10 20 hello
    X Y Z
    1
    2
    3
    4
    5
    Extended Unpacking
    The use case for *
  • 以下の3つの場合はいずれもa割当て1,b割当ての残りである.
  • l = [1,2,3,4,5,6]
    1)
      a = l[0]
      b = [1:]
    2)
      a, b = l[0], l[1:]
    3)
      a, *b = l
  • 3)のように*を使用すると,lがlistでなくてもbのタイプは無条件にlistとなる.
  • 以下を選択することもできます.
  • a, *b, c = [1,2,3,4,5]
    print(a,b,c)
    
    a = [1,2,3]
    b = [4,5,6]
    c = [*a, *b]
    print(c)
    
    a = {"p": 1, "y": 2, "z": 10}
    b = {"t": 3, "h": 4, "z": 50}
    c = {**a, **b}
    print(c) # b의 z가 a의 z를 overwrote함을 주의하라.
    
    d1 = {"a": 1, "b": 2}
    print({"a": 10, **d1})
    
    a, *b, (c, *d) = [1,2,3, "python"]
    print(a,b,c,d)
    1 [2, 3, 4] 5
    [1, 2, 3, 4, 5, 6]
    {'p': 1, 'y': 2, 'z': 50, 't': 3, 'h': 4}
    {'a': 1, 'b': 2}
    1 [2, 3] p ['y', 't', 'h', 'o', 'n']
    *左側でしか使用できません!
    a,b,c=[1,2,3,4,5]は間違っています!
    **左側では使用できません.
    *args
  • argsとは異なります.
  • *は、どの位置argsも受信することを示し、
  • * indicates the "end"of positional arguments
  • と定義されている場合、位置は完全に受け入れられないことを意味します.bはkwargsになった.
  • def my_func(*, b):
        pass
    Parameter defaults: Beware
    デフォルトでは、
  • 関数paramの値が実行時に生成されます.
  • は非常に重要な事実です.次の例です.
  • 実行時のdatetime.now()が生成されるため、3秒sleep以降も同じ値である.
  • from datetime import datetime
    from time import sleep
    def main(t=datetime.now()):
        print(t)
    
    main()
    sleep(3)
    main()
    
    2022-02-11 17:55:09.028305
    2022-02-11 17:55:09.028305
    上記の問題を解決するには、常に関数を呼び出すときに値を渡すか、次の例のように関数に値を定義する必要があります.一般的にdefault valueをNoneと定義するのは国の規定です.
    from datetime import datetime
    from time import sleep
    def main(t=None):
        t = t or datetime.now()
        print(t)
    
    main()
    sleep(3)
    main()
    2022-02-11 17:57:52.713788
    2022-02-11 17:57:55.719404
    default value: mutable object
  • defalut valueでlistなどの変数を使用する場合は、注意してください.
  • は、以下に示すように、望ましくない結果をもたらす可能性があります.
  • 実行時にli=[]が生成され、argsでない限りliが同じメモリを参照し続ける.
  • def main(a, li=[]):
        li.append(a)
        return li
    
    res1 = main(1)
    print(res1)
    res2 = main(3)
    print(res2)
    print(res1)
    print(res1 is res2)
    
    [1]
    [1, 3]
    [1, 3]
    True
    # 해결책
    def main(a, li=None):
        li = li or []
        li.append(a)
        return li
    
    # 의도적으로 함수 param에 mutable을 줄 때도 있다.
    # cache를 반복적으로 쓰려면 아래처럼 해야함.
    def factorial(n, cache={}):
        if n < 1:
            return 1
        elif n in cache:
            return cache[n]
        else:
            print("calculate")
            res = n * factorial(n-1)
            cache[n] = res
            return res
    
    res = factorial(3)
    print(res)
    res = factorial(3)
    print(res)
    calculate
    calculate
    calculate
    6
    6