Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a builtin way to define a function that takes either 1 argument or 3?

There's this error in Python when calling builtin type() with no arguments:

TypeError: type() takes 1 or 3 arguments

How can we define such a method? Is there a builtin way? Or we need to do something like this:

>>> def one_or_three(*args):
...   if len(args) not in [1,3]:
...     raise TypeError("one_or_three() takes 1 or 3 arguments")
... 
>>> one_or_three(1)
>>> one_or_three()
TypeError: one_or_three() takes 1 or 3 arguments
>>> one_or_three(1,2)
TypeError: one_or_three() takes 1 or 3 arguments
like image 443
Adelin Avatar asked Nov 12 '18 12:11

Adelin


People also ask

How do you define a function with multiple arguments?

The * symbol is used to pass a variable number of arguments to a function. Typically, this syntax is used to avoid the code failing when we don't know how many arguments will be sent to the function.

How do you define a function that takes variable number of arguments?

In Python, there are two ways to define a function that can take a variable number of arguments. Different forms of this type are: Positional arguments. Keyword arguments.

How many argument can be used in a function definition?

Except for functions with variable-length argument lists, the number of arguments in a function call must be the same as the number of parameters in the function definition. This number can be zero. The maximum number of arguments (and corresponding parameters) is 253 for a single function.

How do you define a function that takes an argument in Python?

The syntax for calling a Python function is as follows: <function_name>([<arguments>]) <arguments> are the values passed into the function. They correspond to the <parameters> in the Python function definition. You can define a function that doesn't take any arguments, but the parentheses are still required.

How do you define a function that takes an argument?

Related Studylists PythonHResearch work Preview text Example 1: Define a function that takes an argument. Call the function. Identify what code is the argument and what code is the parameter. def hello(name): print(“Hi,”,name) This function is used as follows. &gt; hello(“John”) Hi, John In this case, the argument is John.

How do I write a python function with arguments?

Define a function that takes an argument. Call the function. Identify what code is the argument and what code is the parameter Create your own Python code examples that demonstrate each of the following. Do not copy examples from the book or any other source. Try to be creative with your examples to demonstrate that you invented them yourself.

How many arguments does the introduction function have?

This function, called introduction, has one argument, name. The body of this function includes only one line, which prints out the message, including the name. We have also added a comment explaining the purpose of our function.

What are builtin functions in Python?

Builtin functions are part of the Python language. They are provided to be used in our Python programs. For example, print () function in Python is used to display some output message to the user on the screen. For example, print (‘hello World’) will show a message Hello World on the screen.


2 Answers

First, type is not native Python (at least in CPython), but C.

The inspect module can confirm it easily (even if documented as a builtin function, type is implemented as a class in CPython):

>>> print(inspect.signature(type.__init__))
(self, /, *args, **kwargs)
>>> print(sig.parameters['self'].kind)
POSITIONAL_ONLY

The parameter kind is POSITIONAL_ONLY, which cannot be created in Python.

That means that it will not be possible to reproduce exactly the behaviour of type.

Python source allows only 2 signatures for variable number of arguments:

  • 3 parameters, 2 of them being optional:

    type(object_or_name, bases = None, dict = None)
    

    This would be very different, because it will accept gladly type(obj, None) which is definitely not what is expected here

  • a simple *args parameter whose length will be tested by hand - your proposal. This will be much closer to native type behaviour, because it really requires 1 or 3 parameters, whatever the values.

TL/DR: the answer to your question is that we really need the something like that way.

like image 96
Serge Ballesta Avatar answered Oct 24 '22 05:10

Serge Ballesta


This behavior is perfectly possible in Python.

def one_or_three(one, two=object(), three=object()):
    two_sentinel, three_sentinel = one_or_three.__defaults__
    if (two == two_sentinel) != (three == three_sentinel):
        raise TypeError("one_or_three() takes 1 or 3 arguments")
    ...

This has the benefits of named arguments (semantic value, passing in by name, etc) but is basically a variation on checking the values of some variables to know whether one or three things were passed.

Note that the two calls to object() produce two different objects and bind them to the function:

>>> one_or_three.__defaults__
(<object object at 0x00168540>, <object object at 0x00168ED0>)

This way, they are globally unique. If you instead used None as your sentinel object, then it wouldn't be possible to pass in None as an argument (though of course that may be desired).

like image 27
Joel Harmon Avatar answered Oct 24 '22 05:10

Joel Harmon