[Python-ideas] Optional static typing -- the crossroads
Steven D'Aprano
steve at pearwood.info
Sun Aug 17 04:08:51 CEST 2014
On Sat, Aug 16, 2014 at 01:22:48PM -0700, Ethan Furman wrote:
> As a test case for what code may soon look like, here's a bit from one of
> my code bases:
>
>
> --------------------------------------------------------------------
> class ACHPayment(object):
> """A single payment from company to a vendor."""
>
> def __init__(self,
> description, sec_code,
> vendor_name, vendor_inv_num, vendor_rtng, vendor_acct,
> transaction_code, vendor_acct_type, amount, payment_date):
> """
> description: 10 chars
> sec_code: 'CCD' or 'CTX'
> vendor_name: 22 chars
> vendor_inv_num: 15 chars
> vendor_rtng: 9 chars
> vendor_acct: 17 chars
> transaction_code: ACH_ETC code (enum)
> vendor_acct_type: 'domestic' or 'foreign'
> amount: 10 digits (pennies)
> payment_date: date payment should occur on (datetime.date type
> class)
> """
> --------------------------------------------------------------------
>
>
> The question: what would this look like with type annotations? As a point
> of interest, the last parameter, payment_date, can be /anything/ that
> quacks like a datetime.date -- I tend to use my own dbf.Date class, which
> subclasses object, not datetime.date itself.
I don't think this is a shining example of the value of static typing,
at least not by default. As I see it, you would get something like this:
def __init__(self,
description:str, sec_code:str,
vendor_name:str, vendor_inv_num:str,
vendor_rtng:str, vendor_acct:str,
transaction_code:str, vendor_acct_type:str,
amount:int, payment_date:Any)->None:
which may not give you much additional value. In this case, I think that
the static checks will add nothing except (perhaps) allow you to forgo
writing a few isinstance checks. You still have to check that the
strings are the right length, and so on.
But if you're willing to invest some time creating individual str
subclasses, you can push the length checks into the subclass
constructor, and write something like this:
def __init__(self,
description:Str10, sec_code:SecurityCode,
vendor_name:Str22, vendor_inv_num:Str15,
vendor_rtng:Str9, vendor_acct:Str17,
transaction_code:ACH_ETC, vendor_acct_type:VendorAcctType,
amount:Pennies, payment_date:DateABC)->None:
Without knowing your application in detail, it is difficult to know how
much work you should hand over to the type system, and how much you
should continue to do in Python. If all you're doing is pushing strings
from one place to another, you might not care exactly how long the
string is, say because they're truncated when you print them.
--
Steven
More information about the Python-ideas
mailing list