Asked  7 Months ago    Answers:  5   Viewed   34 times

I've recently noticed something interesting when looking at Python 3.3 grammar specification:

funcdef: 'def' NAME parameters ['->' test] ':' suite

The optional 'arrow' block was absent in Python 2 and I couldn't find any information regarding its meaning in Python 3. It turns out this is correct Python and it's accepted by the interpreter:

def f(x) -> 123:
    return x

I thought that this might be some kind of a precondition syntax, but:

  • I cannot test x here, as it is still undefined,
  • No matter what I put after the arrow (e.g. 2 < 1), it doesn't affect the function behavior.

Could anyone accustomed with this syntax style explain it?

 Answers

16

It's a function annotation.

In more detail, Python 2.x has docstrings, which allow you to attach a metadata string to various types of object. This is amazingly handy, so Python 3 extends the feature by allowing you to attach metadata to functions describing their parameters and return values.

There's no preconceived use case, but the PEP suggests several. One very handy one is to allow you to annotate parameters with their expected types; it would then be easy to write a decorator that verifies the annotations or coerces the arguments to the right type. Another is to allow parameter-specific documentation instead of encoding it into the docstring.

Tuesday, June 1, 2021
 
Corsair
answered 7 Months ago
14

Answer

The & symbol is a bitwise AND operator. Used with 1, it basically masks the value to extract the lowest bit, or in other words will tell you if the value is even or odd.

More Info on Python's & operator

For more information, see: http://wiki.python.org/moin/BitwiseOperators

Why it Works to check Odd vs. Even

EDIT: Adding this section since this answer is getting some love

The reason why ANDing a value with 1 tells if the value is odd or even may not be obvious at first.

The binary representation of a number is essentially the sum of a series of YES or NO for each power of 2 moving leftward starting in the rightmost digit with 1, 2, 4, 8, ...

There is only one way to represent any number in this way. E.g. the number 13 (base 10) can be written in binary as "1101" (or hexadecimal as 0xD, but that's beside the point). See here:

    1   1   0   1
    x   x   x   x
    8   4   2   1
    =   =   =   =
    8 + 4 + 0 + 1  =  13

Notice that aside from the rightmost binary digit, all other 1 digits will add an even number (i.e. a multiple of 2) to the sum. So the only way to get an odd final sum is to add that odd 1 from the rightmost digit. So if we're curious if a number is odd or even, we can look at its binary representation and ignore everything except for the rightmost digit.

To do this, we use the bitwise AND operator. The value 1 in binary is expressed as 1:

    0   0   0   1
    x   x   x   x
    8   4   2   1
    =   =   =   =
    0 + 0 + 0 + 1  =  1

ANDing a value with 1 like this will result in 1 if the value's rightmost bit is set, and 0 if it is not.

And because 0 is generally considered "false" in most languages, and non-zero values considered "true", we can simply say as a shortcut:

if (value & 1): do_something_with_odd_value()...
Wednesday, June 9, 2021
 
Indranil
answered 6 Months ago
98

It's a reference to a pointer to an int. This means the function in question can modify the pointer as well as the int itself.

You can just pass a pointer in, the one complication being that the pointer needs to be an l-value, not just an r-value, so for example

int myint;
function(&myint);

alone isn't sufficient and neither would 0/NULL be allowable, Where as:

int myint;
int *myintptr = &myint;
function(myintptr);

would be acceptable. When the function returns it's quite possible that myintptr would no longer point to what it was initially pointing to.

int *myintptr = NULL;
function(myintptr);

might also make sense if the function was expecting to allocate the memory when given a NULL pointer. Check the documentation provided with the function (or read the source!) to see how the pointer is expected to be used.

Saturday, July 3, 2021
 
alioygur
answered 5 Months ago
58

use the following to convert to a timestamp in python 2

int((mod_time.mktime(first_run.timetuple())+first_run.microsecond/1000000.0))

Sunday, August 22, 2021
 
waylaidwanderer
answered 4 Months ago
17

Just use Algorithm directly:

def get_foo(foo_algorithm: Algorithm):
    return foo_algoritm.foo

and automatically any instance of a subclass will be acceptable (isinstance(foo_algorithm, Algorithm) must be true, which applies to all subclasses of a baseclass).

If you can only accept classes, then use Type[Algorithm] as the type hint:

def get_foo(foo_algorithm: Type[Algorithm]):
    return foo_algoritm().foo

See the The type of class objects section of PEP 484 -- Type Hints:

Sometimes you want to talk about class objects, in particular class objects that inherit from a given class. This can be spelled as Type[C] where C is a class. To clarify: while C (when used as an annotation) refers to instances of class C, Type[C] refers to subclasses of C.

Here I called the class object, since .foo is an instance attribute according to your code example; a class derived from Algorithm would not have such an attribute itself.

Monday, October 18, 2021
 
M.P. Korstanje
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share