It may be a dumb question but what kind of data type is a def from Python in C ?
like int, uint32_t etc.. or nothing of all of this ?
Thanks
def is a keyword in python. (It introduces the definition of functions.) It is not a datatype at all.
def is the Python's keyword that is used at the start of the function/method definition.
C and Python are fundamentally different languages and doing a line by line translation is impossible. To answer your direct question, def is a keyword in Python that only marks the start of a function declaration. There is no such keyword in C. Sure, you need keywords to declare functions, but there is no single keyword that is required.
Furthermore, you cannot compare types either. C has a sh*tload of different types just for integers. Python3 only has one, and it has unlimited precision. Such a type does not exist in C, although there are libraries that provides the same functionality.
Related
Suppose python supported function overloading, how would we define overloaded functions for adding two numbers and concatenating two strings?
I just want to know how do we assign a particular data type to a parameter in the function definition or will it depend on the arguments given in the function call.
Would it be like this:
def num(a=int,b=int):
return a+b
def strng(a=str,b=str):
return a+b
python is dynamically typed language. Hence, type checks are not strictly enforced. In defining a function, you can define an optional type for the parameters.
def function(a:int=0, b:int=0): return a + b
The type definition here really does nothing peculiar but probably helps with IDE autocompletion. You can pass in a string and you won't get any errors but it'll definitely throw an error when adding a number to a string.
I am currently trying to pass a string to a Fortran library. I have gotten other functions from this library to work, but this particular one seems to be unique in that it wants a string passed to it as an argument to the function.
Looking at the source code, the function requires three arguments
SUBROUTINE EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL)
and the arguments are defined:
IMPLICIT NONE
CHARACTER*(*) VOLEQI
CHARACTER*10 VOLEQ
REAL DBHOB,HTTOT,TOPD, VOL(15), MHT
INTEGER REGN,ERRFLG
In Python my call to the function looks like
from ctypes import *
mylib = cdll.LoadLibrary('/home/bryce/Programming/opencompile/libvollib.so')
dbhob = c_float(42.2)
vol = (c_float * 15)()
voleqi = c_char_p("101DVEW119 ")
mylib.ezvollib_(voleqi, dbhob, vol)
This runs without a segmentation fault, but does not seem to "fill" the variable vol with the desired 15 float values.
Is there any way to get vol to retrieve the values being returned from the EZVOLLIB function?
There are many similar questions here, but it is hard to find an exact duplicate. There are several possible ways to do that with different degrees of universal correctness and portability.
The most correct way is to use modern Fortran to C interoperability as explained in fortran77, iso_c_binding and c string That requires writing more Fortran wrapping code.
There are people who are strictly against writing any more Fortran, even-though that is the only portable solution. In that case they must explore what is the actual calling convention for Fortran strings in their compiler. Usually a hidden integer argument with the string length is passed to the subroutine. For gfortran see https://gcc.gnu.org/onlinedocs/gfortran/Argument-passing-conventions.html
Your ctypes interface could employ these compiler-specific calling conventions but then the interface will be, well, compiler-specific. But you are already relying on the specific name mangling ezvollib_ and that is compiler-specific as well. You can find examples here on SO where people were bitten by relying on that.
Also note, as noted by High Performance Mark, that the subroutine in question has four arguments, not three: EZVOLLIB(VOLEQI,DBHOB,HTTOT,VOL). Calling it with just three as in mylib.ezvollib_(voleqi, dbhob, vol) is an error. You are missing the HTTOT argument.
What is the correct name for operator *, as in function(*args)? unpack, unzip, something else?
In Ruby and Perl 6 this has been called "splat", and I think most people from
those communities will figure out what you mean if you call it that.
The Python tutorial uses the phrase "unpacking argument lists", which is
long and descriptive.
It is also referred to as iterable unpacking, or in the case of **,
dictionary unpacking.
I call it "positional expansion", as opposed to ** which I call "keyword expansion".
The Python Tutorial simply calls it 'the *-operator'. It performs unpacking of arbitrary argument lists.
I say "star-args" and Python people seem to know what i mean.
** is trickier - I think just "qargs" since it is usually used as **kw or **kwargs
One can also call * a gather parameter (when used in function arguments definition) or a scatter operator (when used at function invocation).
As seen here: Think Python/Tuples/Variable-length argument tuples.
I believe it's most commonly called the "splat operator." Unpacking arguments is what it does.
The technical term for this is a Variadic function. So in a sense, that's the correct term without regard to programming language.
That said, in different languages the term does have legitimate names. As others have mentioned, it is called "splat" in ruby, julia, and several other languages and is noted by that name in official documentation. In javascript it is called the "spread" syntax. It has many other names in many other languages, as mentioned in other answers. Whatever you call it, it's quite useful!
For a colloquial name there is "splatting".
For arguments (list type) you use single * and for keyword arguments (dictionary type) you use double **.
Both * and ** is sometimes referred to as "splatting".
See for reference of this name being used:
https://stackoverflow.com/a/47875892/14305096
I call *args "star args" or "varargs" and **kwargs "keyword args".
Sometimes I write projects and don't return to them until months later. Unfortunately for me I forget what was intended to be passed into a function. I would like to be able to hover over an argument and see the type such as integer, string, some class, etc. Is there an IDE out there that will do this for me? Any help is appreciated.
There is no way to infer the type normally, so no IDE will be able to do this. Why not just use docstrings?
def foo(a, b):
"""
Take your arguments back, I don't want them!
a -- int
b -- str
"""
return a, b
In Python 3 you could also take advantage of function annotations:
def foo(a: int, b: str):
"""Take your arguments back, I don't want them!"""
return a, b
In Python, it is not possible to generically infer the types of variables without actually running the code and seeing what they end up referencing. And even then, much Python code works on many different types, so there really is no true unique type of a variable.
For example, the any builtin function iterates over its argument and returns True if any of its elements are true. Sounds like a function from list of bool to bool? Wrong. All it needs is something that can be iterated. This includes lists, tuples, dictionaries, sets, generators and more builtin types, not to mention user-defined classes that implement the iterator protocol. So there's no way you can even infer that because any is called on something that it's a list. And any python value (I believe) can be evaluated as true/false in boolean context, so the contents of the sequence don't even have to be bools.
Most code doesn't use the full "dynamism" of Python, and is only expected to put values of a single type in each variable. So theoretically, you could use some annotations and heuristics to do type inference some of the time. I am not aware of any IDE that has attempted to do this, and I don't believe it's actually practical.
Fundamentally, you need documentation on the way your functions/classes should be called and what kinds of things they return. If you lack this knowledge, you will make mistakes whether you have type information or not.
In PyCharm, you can hold CTRL and point at an identifier to see its inferred type. PyCharm can infer many types from assignments and return values, and can also infer argument and return types from both docstrings and python3 function annotations.
While I am aware of the duck-typing concept of Python, I sometimes struggle with the type of arguments of functions, or the type of the return value of the function.
Now, if I wrote the function myself, I DO know the types. But what if somebody wants to use and call my functions, how is he/she expected to know the types?
I usually put type information in the function's docstring (like: "...the id argument should be an integer..." and "... the function will return a (string, [integer]) tuple.")
But is looking up the information in the docstring (and putting it there, as a coder) really the way it is supposed to be done?
Edit: While the majority of answers seem to direct towards "yes, document!" I feel this is not always very easy for 'complex' types. For example: how to describe concisely in a docstring that a function returns a list of tuples, with each tuple of the form (node_id, node_name, uptime_minutes) and that the elements are respectively a string, string and integer?
The docstring PEP documentation doesn't give any guidelines on that.
I guess the counterargument will be that in that case classes should be used, but I find python very flexible because it allows passing around these things using lists and tuples, i.e. without classes.
Well things have changed a little bit since 2011! Now there's type hints in Python 3.5 which you can use to annotate arguments and return the type of your function. For example this:
def greeting(name):
return 'Hello, {}'.format(name)
can now be written as this:
def greeting(name: str) -> str:
return 'Hello, {}'.format(name)
As you can now see types, there's some sort of optional static type checking which will help you and your type checker to investigate your code.
for more explanation I suggest to take a look at the blog post on type hints in PyCharm blog.
This is how dynamic languages work. It is not always a good thing though, especially if the documentation is poor - anyone tried to use a poorly documented python framework? Sometimes you have to revert to reading the source.
Here are some strategies to avoid problems with duck typing:
create a language for your problem domain
this will help you to name stuff properly
use types to represent concepts in your domain language
name function parameters using the domain language vocabulary
Also, one of the most important points:
keep data as local as possible!
There should only be a few well-defined and documented types being passed around. Anything else should be obvious by looking at the code: Don't have weird parameter types coming from far away that you can't figure out by looking in the vicinity of the code...
Related, (and also related to docstrings), there is a technique in python called doctests. Use that to document how your methods are expected to be used - and have nice unit test coverage at the same time!
Actually there is no need as python is a dynamic language, BUT if you want to specify a return value then do this
def foo(a) -> int: #after arrow type the return type
return 1 + a
But it won't really help you much. It doesn't raise exceptions in the same way like in staticly-typed language like java, c, c++. Even if you returned a string, it won't raise any exceptions.
and then for argument type do this
def foo(a: int) -> int:
return a+ 1
after the colon (:)you can specify the argument type.
This won't help either, to prove this here is an example:
def printer(a: int) -> int: print(a)
printer("hello")
The function above actually just returns None, because we didn't return anything, but we did tell it we would return int, but as I said it doesn't help. Maybe it could help in IDEs (Not all but few like pycharm or something, but not on vscode)
I attended a coursera course, there was lesson in which, we were taught about design recipe.
Below docstring format I found preety useful.
def area(base, height):
'''(number, number ) -> number #**TypeContract**
Return the area of a tring with dimensions base #**Description**
and height
>>>area(10,5) #**Example **
25.0
>>area(2.5,3)
3.75
'''
return (base * height) /2
I think if docstrings are written in this way, it might help a lot to developers.
Link to video [Do watch the video] : https://www.youtube.com/watch?v=QAPg6Vb_LgI
Yes, you should use docstrings to make your classes and functions more friendly to other programmers:
More: http://www.python.org/dev/peps/pep-0257/#what-is-a-docstring
Some editors allow you to see docstrings while typing, so it really makes work easier.
Yes it is.
In Python a function doesn't always have to return a variable of the same type (although your code will be more readable if your functions do always return the same type). That means that you can't specify a single return type for the function.
In the same way, the parameters don't always have to be the same type too.
For example: how to describe concisely in a docstring that a function returns a list of tuples, with each tuple of the form (node_id, node_name, uptime_minutes) and that the elements are respectively a string, string and integer?
Um... There is no "concise" description of this. It's complex. You've designed it to be complex. And it requires complex documentation in the docstring.
Sorry, but complexity is -- well -- complex.
Answering my own question >10 years later, there are now 2 things I use to manage this:
type hints (as already mentioned in other answers)
dataclasses, when parameter or return type hints become unwieldy/hard to read
As an example of the latter, say I have a function
def do_something(param:int) -> list[tuple[list, int|None]]:
...
return result
I would now rewrite using a dataclass, e.g. along the lines of:
from dataclasses import dataclass
#dataclass
class Stat:
entries: list
value: int | None = None
def do_something(param:int) -> list[Stat]:
...
return result
Yes, since it's a dynamically type language ;)
Read this for reference: PEP 257
Docstrings (and documentation in general). Python 3 introduces (optional) function annotations, as described in PEP 3107 (but don't leave out docstrings)