개발/Python

[파이썬] 선택적 인수가 있는 함수를 정의하는 방법

MinorMan 2023. 1. 21. 22:55
반응형

<질문>

여러 인수를 취하는 Python 함수가 있습니다. 이러한 인수 중 일부는 일부 시나리오에서 생략될 수 있습니다.

def some_function (self, a, b, c, d = None, e = None, f = None, g = None, h = None):
    #code

인수d~을 통해h각각 다른 의미를 갖는 문자열입니다. 어떤 조합으로 전달할 선택적 매개변수를 선택할 수 있는지가 중요합니다. 예를 들어,(a, b, C, d, e), 또는(a, b, C, g, h), 또는(a, b, C, d, e, f, 또는 그들 모두 (이것은 내 선택입니다).

함수를 오버로드할 수 있다면 좋겠지만 Python은 오버로드를 지원하지 않는다는 것을 읽었습니다. 필요한 int 인수 중 일부를 목록에 삽입하려고 했는데 인수 불일치 오류가 발생했습니다.

지금은 처음 몇 개의 누락된 인수 대신 자리 표시자로 빈 문자열을 보내고 있습니다. 실제 값을 사용하여 함수를 호출할 수 있기를 원합니다.

이 작업을 수행할 수 있는 방법이 있습니까? 인수 목록 대신 목록을 전달할 수 있습니까?

현재 ctypes를 사용하는 프로토타입은 다음과 같습니다.

_fdll.some_function.argtypes = [c_void_p, c_char_p, c_int, c_char_p, c_char_p, c_char_p, c_char_p, c_char_p]

<답변1>

그냥 사용*args매개변수를 사용하면 원하는 만큼 인수를 전달할 수 있습니다.a,b,c. 지도에 몇 가지 논리를 추가해야 합니다.args->c,d,e,f그러나 과부하의 "방법"입니다.

def myfunc(a,b, *args, **kwargs):
   for ar in args:
      print ar
myfunc(a,b,c,d,e,f)

그리고 다음 값을 인쇄합니다.c,d,e,f

마찬가지로 다음을 사용할 수 있습니다.kwargs매개변수 이름을 지정할 수 있습니다.

def myfunc(a,b, *args, **kwargs):
      c = kwargs.get('c', None)
      d = kwargs.get('d', None)
      #etc
myfunc(a,b, c='nick', d='dog', ...)

그리고kwargs뒤에 키 값이 있는 모든 매개변수의 사전이 있습니다.a,b


<답변2>

다음과 같이 호출해 보십시오.obj.some_function( '1', 2, '3', g="foo", h="bar" ). 필수 위치 인수 다음에 특정 선택적 인수를 이름으로 지정할 수 있습니다.


<답변3>

이거만 하시면 아주 쉽습니다

def foo(a = None):
       print(a)

None 대신 예를 들어 다음과 같이 매개변수의 값을 쓰지 않을 경우 인수가 없는 경우 제자리에 있어야 하는 모든 것을 입력할 수 있습니다.foo()그런 다음 인수가 제공되지 않았기 때문에 None을 인쇄하고 다음과 같은 인수를 제공하면foo("hello world")그러면 인쇄됩니다hello world... 아, 이런 유형의 매개변수, 즉 선택적 매개변수,다른 모든 매개변수 뒤에 있어야 합니다.이것은 이전 함수를 사용하고 다른 매개변수를 추가하자는 것을 의미합니다.b

def foo(a = None, b): 
    print(a)

이제 파이썬 파일을 실행하면 다음과 같은 예외가 발생합니다.Non-default arguments follow default arguments,

SyntaxError: non-default argument follows default argument

따라서 필수 인수 뒤에 선택적 또는 기본이 아닌 인수를 넣어야 합니다.

def foo (a, b=None): ... #This one is right
def foo(b=None, a): ... #and this isn't

<답변4>

필수 매개변수가 먼저, 선택적 매개변수가 뒤에 있습니다. 선택적 매개변수는 항상=None.

쉽고 빠른 예:

def example_function(param1, param2, param3=None, param4=None):
    pass

# Doesn't work, param2 missing
example_function("hello")

# Works
example_function("hello", "bye")

# Works. Both the same
example_function("hello", "bye", "hey")
example_function("hello", "bye", param3="hey")

# Works. Both the same
example_function("hello", "bye", "hey", "foo")
example_function("hello", "bye", param3="hey", param4="foo")

<답변5>

이것을 확인하십시오:

from typing import Optional

def foo(a: str, b: Optional[str] = None) -> str or None:
    pass

<답변6>

매개변수를 전달할 때 무엇이 가능한지 더 잘 이해하려면 다음과 같은 다양한 옵션을 참조하는 것이 정말 도움이 됩니다. 위치 또는 키워드(arg또는arg="default_value"), 위치 전용(이전/,매개변수 목록에서), 키워드 전용(이후*,매개변수 목록에서), var-positional(일반적으로*args) 또는 var-키워드(일반적으로**kwargs). 훌륭한 방법은 Python 설명서를 참조하십시오.summary; 질문에 대한 다양한 다른 답변은 이러한 변형의 대부분을 사용합니다.

예제에는 항상 매개변수 a, b, c가 있고 위치 지정 방식으로 호출하는 것처럼 보이므로/,,

def some_function (self, a, b, c, /, d = None, e = None, f = None, g = None, h = None):
    #code

<답변7>

벡터 인수 입력에 대해 Avión의 답변이 작동하도록 하려면;

def test(M,v=None):
    try: 
        if (v==None).all() == False:
            print('argument passed')
            return M + v 
    except: 
        print('no argument passed')
        return M 

여기서 M은 행렬이고 v는 벡터입니다. test(M) 및 test(M,v) 모두 'try/except' 문을 사용하지 않고 if 문을 사용하려고 하면 오류가 발생합니다.

cem이 언급했듯이 python 3.10으로 업그레이드하면 통합(x|y)(또는 선택적[...]) 기능이 허용되어 대체 방법에 대한 문을 열 수 있지만 Anaconda 스파이더를 사용하고 있으므로 다음과 같이 생각합니다. 새 릴리스가 Python 3.10을 사용하기를 기다립니다.

반응형