On Fri, Jun 8, 2018 at 10:47 PM Wes Turner <wes.turner@gmail.com> wrote:
Python parameter and return type hints are expressed as function annotations which import and derive types from the typing module and the typeshed. 

- PEP 3107 -- Function Annotations
  https://www.python.org/dev/peps/pep-3107/

- PEP 0484 -- Type Hints
  https://www.python.org/dev/peps/pep-0484/

  - https://www.python.org/dev/peps/pep-0484/#function-method-overloading
  - https://www.python.org/dev/peps/pep-0484/#the-typing-module
    - https://docs.python.org/3/library/typing.html#classes-functions-and-decorators

- https://docs.python.org/3/tutorial/controlflow.html#function-annotations

- from typing import List, MutableMapping, Hashable, Iterable, AsyncGenerator
  https://docs.python.org/3/library/typing.html#classes-functions-and-decorators

- https://github.com/python/typeshed
  - https://github.com/python/typeshed/tree/master/third_party/2and3

  - FunctionType, CodeType,
    MappingProxyType, SimpleNamespace,
    GeneratorType, AsyncGeneratorType,
    CoroutineType,
    MethodType, BuiltinFunctionType,
    TracebackType, FrameType
  https://github.com/python/typeshed/blob/master/stdlib/3/types.pyi#L25 
  https://github.com/python/typeshed/blob/master/stdlib/3/inspect.pyi



On Fri, Jun 8, 2018 at 6:37 PM kirby urner <kirby.urner@gmail.com> wrote:

I enjoyed our discussion of post-its versus buckets, or not versus:  objects in memory take up space, and so are bucket-like, but look how many labels (post-its) some of them have!

sys.getrefcount(None)
 

I find it useful to have memory take shape as something finite, even when we're enjoying more of it on contemporary devices.  Python is biased against making gratuitous copies, or against copying gratuitously, we maybe could say.  

Memory is respected.  L.sort() is "in place" whereas sorted(L) leaves L untouched.  This "inplace" idea carries forward as a keyword argument (named parameter) in many cases.

I confess, in my own courses, I could do more with deepcopy, explaining what it is and how to do it.  I'll get on it.  

https://docs.python.org/3/library/copy.html
 

- copy()
- deepcopy()

- PyDict_copy

- pprint(depth=n)
  a, b = [1,], [2,]
  a.append(a)
  pprint.pprint(a)
  pprint.pprint(a, depth=1)
  

"Why are these methods faster?"

When is it a copy, when a view? is a discussion in pandas as well.
  - zero-copy streaming data 


Another topic:

Another pair of categories I like to tease apart are function versus type, when it comes to what's a callable.  

range() used to be a function that returned a list.  Now it returns an instance of the range type, a sequence.  More like dict(), int() and so on.  Not like hex().

enumerate() and zip() are likewise calls to classes, triggers to __init__s (birth methods).  We're asking for instances.  We're calling types.

Functions return objects too, so one should not say the difference is whether they return objects.  Both do.  

The difference is instances of a type live on with the methods of that type, whereas a function does not directly bequeath its methods to any "children".

class A(): pass
def func(): print(1)
A.__dict__['func'] = func
a = ()
a.__dict__['here'] = func
a.__class__.__dict__['func2'] = func
b = A()
assert hasattr(b, 'here') == False
assert hasattr(a, 'func') == True
assert hasattr(a, 'func2') == True
# isinstance / MRO
 

Functions are factories of other than instances of themselves, even if they return other functions.

What nuances this view is that FunctionType is a type of object, so calling a function is calling a type.  

However, the way a function responds to being called is like an instance does when its type has a __call__ method defined.

Is a generator a callable?
 

===

One of my favorite ways to connect classes and functions is to show how a class might "eat" a function such that the function remains callable, and yet the instances may also multiply, in which case the functions compose to create other functions:

@Composable  # class
def F(x):
    return x + 2

@Composable  # class
def G(x):
    return 2 * x

H = F * F * F * G * G

(H is now a "pipeline" of F(F(F(G(G(x)))))  )

    "The fn.py fn.monad.optionable decorator — @optionable — makes functional composition with chaining easy, too: https://github.com/kachayev/fn.py/blob/master/README.rst#functional-style-for-error-handling
"
 

More on REPL.it:

https://repl.it/@kurner/Composing-Functions

(red X warning flag next to lambda expression is bogus, runs fine, Spyder is smarter)

Kirby

PS:  this morning I saw Guido's talk at Stanford on type annotations, which he recently tweeted about [1].  I definitely include mentioning to be on the lookout for such syntax going forward, and not being thrown by it.  I emphasize that standard core Python sees annotations more as a type of documentation, with 3rd party hooks understanding them more as directives.

Is there anything to do runtime type checking from annotations (just like pycontracts; maybe even with the additional constraints language)?

 
_______________________________________________
Edu-sig mailing list
Edu-sig@python.org
https://mail.python.org/mailman/listinfo/edu-sig