Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #51978 > unrolled thread

Newbie: static typing?

Started byRui Maciel <rui.maciel@gmail.com>
First post2013-08-05 21:46 +0100
Last post2013-08-06 15:05 +0000
Articles 20 on this page of 29 — 15 participants

Back to article view | Back to comp.lang.python


Contents

  Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-05 21:46 +0100
    Re: Newbie: static typing? Gary Herron <gary.herron@islandtraining.com> - 2013-08-05 14:07 -0700
      Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 10:05 +0100
        Re: Newbie: static typing? Steven D'Aprano <steve@pearwood.info> - 2013-08-06 09:26 +0000
        Re: Newbie: static typing? Joshua Landau <joshua@landau.ws> - 2013-08-06 10:29 +0100
          Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 11:12 +0100
            Re: Newbie: static typing? Burak Arslan <burak.arslan@arskom.com.tr> - 2013-08-06 16:27 +0300
            Re: Newbie: static typing? Antoon Pardon <antoon.pardon@rece.vub.ac.be> - 2013-08-06 15:57 +0200
            Re: Newbie: static typing? Chris Angelico <rosuav@gmail.com> - 2013-08-06 15:06 +0100
            Re: Newbie: static typing? "Eric S. Johansson" <esj@harvee.org> - 2013-08-06 09:58 -0400
            Re: Newbie: static typing? Chris Angelico <rosuav@gmail.com> - 2013-08-06 15:38 +0100
        Easier to Ask Forgiveness than Permission (was: Newbie: static typing?) Ben Finney <ben+python@benfinney.id.au> - 2013-08-07 08:23 +1000
    Re: Newbie: static typing? Ian Kelly <ian.g.kelly@gmail.com> - 2013-08-05 17:38 -0600
    Re: Newbie: static typing? Ben Finney <ben+python@benfinney.id.au> - 2013-08-06 10:35 +1000
      Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 10:01 +0100
        Re: Newbie: static typing? Joshua Landau <joshua@landau.ws> - 2013-08-06 10:19 +0100
          Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 11:07 +0100
            Re: Newbie: static typing? Rotwang <sg552@hotmail.co.uk> - 2013-08-06 15:25 +0100
            Re: Newbie: static typing? Ben Finney <ben+python@benfinney.id.au> - 2013-08-07 08:34 +1000
        Re: Newbie: static typing? Chris Angelico <rosuav@gmail.com> - 2013-08-06 10:29 +0100
          Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 11:28 +0100
            Re: Newbie: static typing? Chris Angelico <rosuav@gmail.com> - 2013-08-06 11:50 +0100
            Re: Newbie: static typing? Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2013-08-06 18:54 -0400
            Re: Newbie: static typing? Terry Reedy <tjreedy@udel.edu> - 2013-08-06 19:02 -0400
            Re: Newbie: static typing? Chris Angelico <rosuav@gmail.com> - 2013-08-07 01:16 +0100
            RE: Newbie: static typing? "Prasad, Ramit" <ramit.prasad@jpmorgan.com.dmarc.invalid> - 2013-08-08 16:46 +0000
    Re: Newbie: static typing? Steven D'Aprano <steve@pearwood.info> - 2013-08-06 05:21 +0000
      Re: Newbie: static typing? Rui Maciel <rui.maciel@gmail.com> - 2013-08-06 10:04 +0100
    Re: Newbie: static typing? Grant Edwards <invalid@invalid.invalid> - 2013-08-06 15:05 +0000

Page 1 of 2  [1] 2  Next page →


#51978 — Newbie: static typing?

FromRui Maciel <rui.maciel@gmail.com>
Date2013-08-05 21:46 +0100
SubjectNewbie: static typing?
Message-ID<ktp2jh$3a3$1@dont-email.me>
Is there any pythonic way to perform static typing?  After searching the web 
I've stumbled on a significant number of comments that appear to cover 
static typing as a proof of concept , but in the process I've found no 
tutorial on how to implement it.

Does anyone care to enlighten a newbie?


Thanks in advance,
Rui Maciel

[toc] | [next] | [standalone]


#51979

FromGary Herron <gary.herron@islandtraining.com>
Date2013-08-05 14:07 -0700
Message-ID<mailman.218.1375737396.1251.python-list@python.org>
In reply to#51978
On 08/05/2013 01:46 PM, Rui Maciel wrote:
> Is there any pythonic way to perform static typing?  After searching the web
> I've stumbled on a significant number of comments that appear to cover
> static typing as a proof of concept , but in the process I've found no
> tutorial on how to implement it.
>
> Does anyone care to enlighten a newbie?
>
>
> Thanks in advance,
> Rui Maciel

The Pythonic way is to *enjoy* the freedom and flexibility and power of 
dynamic typing.  If you are stepping out of a static typing language 
into Python, don't step just half way.  Embrace dynamic typing.  (Like 
any freedom, it can bite you at times, but that's no reason to hobble 
Python with static typing.)


Python is both dynamically typed and strongly typed.  If you are 
confusing dynamic/static typing with week/strong typing, see
http://wiki.python.org/moin/Why%20is%20Python%20a%20dynamic%20language%20and%20also%20a%20strongly%20typed%20language

Gary Herron



[toc] | [prev] | [next] | [standalone]


#52006

FromRui Maciel <rui.maciel@gmail.com>
Date2013-08-06 10:05 +0100
Message-ID<ktqdt2$v3k$3@dont-email.me>
In reply to#51979
Gary Herron wrote:

> The Pythonic way is to *enjoy* the freedom and flexibility and power of
> dynamic typing.  If you are stepping out of a static typing language
> into Python, don't step just half way.  Embrace dynamic typing.  (Like
> any freedom, it can bite you at times, but that's no reason to hobble
> Python with static typing.)


What's the Python way of dealing with objects being passed to a function 
that aren't of a certain type, have specific attributes of a specific type, 
nor support a specific interface?


Rui Maciel

[toc] | [prev] | [next] | [standalone]


#52011

FromSteven D'Aprano <steve@pearwood.info>
Date2013-08-06 09:26 +0000
Message-ID<5200c15a$0$29986$c3e8da3$5496439d@news.astraweb.com>
In reply to#52006
On Tue, 06 Aug 2013 10:05:57 +0100, Rui Maciel wrote:

> What's the Python way of dealing with objects being passed to a function
> that aren't of a certain type, have specific attributes of a specific
> type, nor support a specific interface?

Raise TypeError, or just let the failure occurs however it occurs, 
depending on how much you care about early failure.

Worst:

if type(obj) is not int:
    raise TypeError("obj must be an int")


Better, because it allows subclasses:

if not isinstance(obj, int):
    raise TypeError("obj must be an int")


Better still:

import numbers
if not isinstance(obj, numbers.Integer):
    raise TypeError("obj must be an integer number")



All of the above is "look before you leap". Under many circumstances, it 
is "better to ask for forgiveness than permission" by just catching the 
exception:

try:
    flag = obj & 8
except TypeError:
    flag = False


Or just don't do anything:


flag = obj & 8


If obj is the wrong type, you will get a perfectly fine exception at run-
time. Why do extra work do try to detect the failure when Python will do 
it for you?



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#52013

FromJoshua Landau <joshua@landau.ws>
Date2013-08-06 10:29 +0100
Message-ID<mailman.234.1375781395.1251.python-list@python.org>
In reply to#52006
On 6 August 2013 10:05, Rui Maciel <rui.maciel@gmail.com> wrote:
> Gary Herron wrote:
>
>> The Pythonic way is to *enjoy* the freedom and flexibility and power of
>> dynamic typing.  If you are stepping out of a static typing language
>> into Python, don't step just half way.  Embrace dynamic typing.  (Like
>> any freedom, it can bite you at times, but that's no reason to hobble
>> Python with static typing.)
>
> What's the Python way of dealing with objects being passed to a function
> that aren't of a certain type, have specific attributes of a specific type,
> nor support a specific interface?

What's the actual problem you're facing? Where do you feel that you
need to verify types?

[toc] | [prev] | [next] | [standalone]


#52019

FromRui Maciel <rui.maciel@gmail.com>
Date2013-08-06 11:12 +0100
Message-ID<ktqhpq$hu5$2@dont-email.me>
In reply to#52013
Joshua Landau wrote:

> What's the actual problem you're facing? Where do you feel that you
> need to verify types?

A standard case would be when there's a function which is designed expecting 
that all operands support a specific interface or contain specific 
attributes.

In other words, when passing an unsupported type causes problems.


Rui Maciel

[toc] | [prev] | [next] | [standalone]


#52039

FromBurak Arslan <burak.arslan@arskom.com.tr>
Date2013-08-06 16:27 +0300
Message-ID<mailman.251.1375795964.1251.python-list@python.org>
In reply to#52019
On 08/06/13 13:12, Rui Maciel wrote:
> Joshua Landau wrote:
>
>> What's the actual problem you're facing? Where do you feel that you
>> need to verify types?
> A standard case would be when there's a function which is designed expecting 
> that all operands support a specific interface or contain specific 
> attributes.
>
> In other words, when passing an unsupported type causes problems.
>

Hi,

First, let's get over the fact that, with dynamic typing, code fails at
runtime. Irrespective of language, you just shouldn't ship untested
code, so I say that's not an argument against dynamic typing.

This behaviour is only a problem when code fails *too late* into the
runtime -- i.e. when you don't see the offending value in the stack trace.

For example, consider you append values to a list and the values in that
list get processed somewhere else. If your code fails because of an
invalid value, your stack trace is useless, because that value should
not be there in the first place. The code should fail when appending to
that list and not when processing it.

The "too late" case is a bit tough to illustrate. This could be a rough
example: https://gist.github.com/plq/6163839 Imagine that the list there
is progressively constructed somewhere else in the code and later
processed by the sq_all function. As you can see, the stack trace is
pretty useless as we don't see how that value got there.

In such cases, you do need manual type checking.

Yet, as someone else noted, naively using isinstance() for type checking
breaks duck typing. So you should read up on abstract base classes:
http://docs.python.org/2/glossary.html#term-abstract-base-class

These said, I've been writing Python for several years now, and I only
needed to resort to this technique only once. (i was working on a
compiler) Most of the time, you'll be just fine without any manual type
checking.

Best regards,
Burak

[toc] | [prev] | [next] | [standalone]


#52041

FromAntoon Pardon <antoon.pardon@rece.vub.ac.be>
Date2013-08-06 15:57 +0200
Message-ID<mailman.253.1375797454.1251.python-list@python.org>
In reply to#52019
Op 06-08-13 15:27, Burak Arslan schreef:
> On 08/06/13 13:12, Rui Maciel wrote:
>> Joshua Landau wrote:
>>
>>> What's the actual problem you're facing? Where do you feel that you
>>> need to verify types?
>> A standard case would be when there's a function which is designed expecting 
>> that all operands support a specific interface or contain specific 
>> attributes.
>>
>> In other words, when passing an unsupported type causes problems.
>>
> 
> Hi,
> 
> First, let's get over the fact that, with dynamic typing, code fails at
> runtime. Irrespective of language, you just shouldn't ship untested
> code, so I say that's not an argument against dynamic typing.

Why not? Can ease of development not be a consideration? So if some
kind of faults are easier to detect at compile time if you have static
typing than if you have to design a test for them, I don't see why that
can't be an argument.

-- 
Antoon Pardon

[toc] | [prev] | [next] | [standalone]


#52043

FromChris Angelico <rosuav@gmail.com>
Date2013-08-06 15:06 +0100
Message-ID<mailman.255.1375798002.1251.python-list@python.org>
In reply to#52019
On Tue, Aug 6, 2013 at 2:57 PM, Antoon Pardon
<antoon.pardon@rece.vub.ac.be> wrote:
> Op 06-08-13 15:27, Burak Arslan schreef:
>> On 08/06/13 13:12, Rui Maciel wrote:
>>> Joshua Landau wrote:
>>>
>>>> What's the actual problem you're facing? Where do you feel that you
>>>> need to verify types?
>>> A standard case would be when there's a function which is designed expecting
>>> that all operands support a specific interface or contain specific
>>> attributes.
>>>
>>> In other words, when passing an unsupported type causes problems.
>>>
>>
>> Hi,
>>
>> First, let's get over the fact that, with dynamic typing, code fails at
>> runtime. Irrespective of language, you just shouldn't ship untested
>> code, so I say that's not an argument against dynamic typing.
>
> Why not? Can ease of development not be a consideration? So if some
> kind of faults are easier to detect at compile time if you have static
> typing than if you have to design a test for them, I don't see why that
> can't be an argument.

Sure, which is why I like working in Pike, which does have static type
declarations (when you want them; they can get out the way when you
don't). But there will always be, regardless of your language,
criteria that static typing cannot adequately handle, so just write
your code to cope with exceptions - much easier. If the exception's
never thrown, the bug can't be all that serious; otherwise, just deal
with it when you find it, whether that be in initial testing or years
later in production. There WILL BE such errors - that's a given. Deal
with them, rather than trying to eliminate them.

ChrisA

[toc] | [prev] | [next] | [standalone]


#52044

From"Eric S. Johansson" <esj@harvee.org>
Date2013-08-06 09:58 -0400
Message-ID<mailman.256.1375798295.1251.python-list@python.org>
In reply to#52019
On Tue, 06 Aug 2013 09:27:10 -0400, Burak Arslan  
<burak.arslan@arskom.com.tr> wrote:

> First, let's get over the fact that, with dynamic typing, code fails at
> runtime. Irrespective of language, you just shouldn't ship untested
> code, so I say that's not an argument against dynamic typing.

It's not so much shipping untested code as not having or unable to test  
all the pathways in the code shipped. I ran into this problem with a  
server I built. I ended up solving the problem by building a testing  
scaffolding that let me control all inputs. It would've been much easier  
with static typing to make sure all the pieces lined up.

The other technique I've used is a properly set up exception handling  
environment. Do it right and you can log all of the errors so that you  
have useful information. Part of "doing it right" includes a system that  
tells you when exceptions happened right away so the server doesn't run  
for days or more failing at random but nobody notices because your  
exceptions keep the system for failing completely.

I guess this is a long way of saying instrument your software so that it  
can be tested and or give you enough information about the internal state.  
This is sort of like building a specialized integrated circuit. You need  
to design it so it can be tested/observed after it's been embedded in  
epoxy and not just count on being able to probe the wafer in the lab.

[toc] | [prev] | [next] | [standalone]


#52048

FromChris Angelico <rosuav@gmail.com>
Date2013-08-06 15:38 +0100
Message-ID<mailman.259.1375799911.1251.python-list@python.org>
In reply to#52019
On Tue, Aug 6, 2013 at 2:58 PM, Eric S. Johansson <esj@harvee.org> wrote:
> I guess this is a long way of saying instrument your software so that it can
> be tested and or give you enough information about the internal state. This
> is sort of like building a specialized integrated circuit. You need to
> design it so it can be tested/observed after it's been embedded in epoxy and
> not just count on being able to probe the wafer in the lab.

In software, that's easy: just have a way to execute arbitrary code in
the context of the running server. A *hugely* beneficial debugging
tool. Of course, it's also a security concern, so you have to put a
good password [1] on it, or have some other system for guaranteeing
that untrusted persons can't execute arbitrary code.

ChrisA

[1] By which I mean http://xkcd.com/936/ compliant.

[toc] | [prev] | [next] | [standalone]


#52073 — Easier to Ask Forgiveness than Permission (was: Newbie: static typing?)

FromBen Finney <ben+python@benfinney.id.au>
Date2013-08-07 08:23 +1000
SubjectEasier to Ask Forgiveness than Permission (was: Newbie: static typing?)
Message-ID<mailman.275.1375827802.1251.python-list@python.org>
In reply to#52006
Rui Maciel <rui.maciel@gmail.com> writes:

> Gary Herron wrote:
>
> > The Pythonic way is to *enjoy* the freedom and flexibility and power
> > of dynamic typing. If you are stepping out of a static typing
> > language into Python, don't step just half way. Embrace dynamic
> > typing. (Like any freedom, it can bite you at times, but that's no
> > reason to hobble Python with static typing.)
>
> What's the Python way of dealing with objects being passed to a
> function that aren't of a certain type, have specific attributes of a
> specific type, nor support a specific interface?

Python has strong typing. That means every Python object (and in Python,
every value is an object) knows what its type is and therefore what
behaviours it supports.

Types (that is, classes; the two terms refer to the same thing in
Python) are the correct place to put checks on whether the type's
instances are being used properly.

Don't check types of objects in every place where you use those objects.
(This is a sub-set of Look Before You Leap programming, which is
discouraged because it makes your code far too heavy on checking for
problems rather than the purpose of the code.)

Check for type appropriate usage in the type itself.

So the Pythonic way to deal with objects that don't support particular
behaviour is: Use the object on the assumption that it supports the
behaviour you want – that is, assume the caller of your function is
giving you an object that your function can use. If the object doesn't
support that behaviour, an error will be raised from the type.

Sometimes your function will know exactly what to do with an error, and
can give more specific information about the problem. In those cases,
you should catch the exception and ‘raise MoreSpecificError("foo") from
exc’. But only in those cases where your function *actually does* know
more about the problem.

In the majority of cases, don't check the type at all, and allow the
type-specific error to raise back to the caller, who then has to deal
with the fact they've passed your function an object that doesn't
support the necessary behaviour.

This principle – of assuming the behaviour is supported, and having a
robust infrastructure for dealing with errors – is known as Easier to
Ask Forgiveness than Permission.

In Python, we discourage LBYL and encourage EAFP. Our code tends to have
a lot less boiler-plate and obfuscatory error-checking as a result, and
tends to be more expressive than statically-typed languages.

-- 
 \       “If you make people think they're thinking, they'll love you; |
  `\     but if you really make them think, they'll hate you.” —Donald |
_o__)                                             Robert Perry Marquis |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#51988

FromIan Kelly <ian.g.kelly@gmail.com>
Date2013-08-05 17:38 -0600
Message-ID<mailman.222.1375745960.1251.python-list@python.org>
In reply to#51978
On Mon, Aug 5, 2013 at 2:46 PM, Rui Maciel <rui.maciel@gmail.com> wrote:
> Is there any pythonic way to perform static typing?  After searching the web
> I've stumbled on a significant number of comments that appear to cover
> static typing as a proof of concept , but in the process I've found no
> tutorial on how to implement it.
>
> Does anyone care to enlighten a newbie?

Python 3 has support for function annotations, but it leaves it
entirely up to the user how they wish to use these annotations (if at
all).  In theory, a Python IDE could use function annotations to
perform static type checking, but I am not aware of any IDE that has
actually implemented this.

[toc] | [prev] | [next] | [standalone]


#51989

FromBen Finney <ben+python@benfinney.id.au>
Date2013-08-06 10:35 +1000
Message-ID<mailman.223.1375749359.1251.python-list@python.org>
In reply to#51978
Rui Maciel <rui.maciel@gmail.com> writes:

> Is there any pythonic way to perform static typing?

I think no; static typing is inherently un-Pythonic.

Python provides strong, dynamic typing. Enjoy it!

> Does anyone care to enlighten a newbie?

Is there some specific problem you think needs static typing? Perhaps
you could start a new thread, giving an example where you are having
trouble and you think static typing would help.

-- 
 \        “Pinky, are you pondering what I'm pondering?” “Wuh, I think |
  `\    so, Brain, but will they let the Cranberry Duchess stay in the |
_o__)                         Lincoln Bedroom?” —_Pinky and The Brain_ |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#52004

FromRui Maciel <rui.maciel@gmail.com>
Date2013-08-06 10:01 +0100
Message-ID<ktqdkq$v3k$1@dont-email.me>
In reply to#51989
Ben Finney wrote:

> Rui Maciel <rui.maciel@gmail.com> writes:
> 
>> Is there any pythonic way to perform static typing?
> 
> I think no; static typing is inherently un-Pythonic.
> 
> Python provides strong, dynamic typing. Enjoy it!

Bummer. 


>> Does anyone care to enlighten a newbie?
> 
> Is there some specific problem you think needs static typing? Perhaps
> you could start a new thread, giving an example where you are having
> trouble and you think static typing would help.

It would be nice if some functions threw an error if they were passed a type 
they don't support or weren't designed to handle.  That would avoid having 
to deal with some bugs which otherwise would never happen.  

To avoid this sort of error, I've been testing arguments passed to some 
functions based on their type, and raising TypeError when necessariy, but 
surely there must be a better, more pythonic way to handle this issue.


Rui Maciel

[toc] | [prev] | [next] | [standalone]


#52010

FromJoshua Landau <joshua@landau.ws>
Date2013-08-06 10:19 +0100
Message-ID<mailman.232.1375780843.1251.python-list@python.org>
In reply to#52004
On 6 August 2013 10:01, Rui Maciel <rui.maciel@gmail.com> wrote:
> Ben Finney wrote:
>
>> Rui Maciel <rui.maciel@gmail.com> writes:
>>
>>> Is there any pythonic way to perform static typing?
>>
>> I think no; static typing is inherently un-Pythonic.
>>
>> Python provides strong, dynamic typing. Enjoy it!
>
> Bummer.

It's really not.


>>> Does anyone care to enlighten a newbie?
>>
>> Is there some specific problem you think needs static typing? Perhaps
>> you could start a new thread, giving an example where you are having
>> trouble and you think static typing would help.
>
> It would be nice if some functions threw an error if they were passed a type
> they don't support or weren't designed to handle.  That would avoid having
> to deal with some bugs which otherwise would never happen.
>
> To avoid this sort of error, I've been testing arguments passed to some
> functions based on their type, and raising TypeError when necessariy, but
> surely there must be a better, more pythonic way to handle this issue.

Unless you have a very good reason, don't do this. It's a damn pain
when functions won't accept my custom types with equivalent
functionality -- Python's a duck-typed language and it should behave
like one.

[toc] | [prev] | [next] | [standalone]


#52018

FromRui Maciel <rui.maciel@gmail.com>
Date2013-08-06 11:07 +0100
Message-ID<ktqhhb$hu5$1@dont-email.me>
In reply to#52010
Joshua Landau wrote:

> Unless you have a very good reason, don't do this. It's a damn pain
> when functions won't accept my custom types with equivalent
> functionality -- Python's a duck-typed language and it should behave
> like one.

In that case what's the pythonic way to deal with standard cases like this 
one?

<code>
class SomeModel(object):
        def __init__(self):
                self.label = "this is a label attribute"

        def accept(self, visitor):
                visitor.visit(self)
                print("visited: ", self.label)


class AbstractVisitor(object):
        def visit(self, element):
                pass
    

class ConcreteVisitorA(AbstractVisitor):
        def visit(self, element):
                element.label = "ConcreteVisitorA operated on this model"

class ConcreteVisitorB(AbstractVisitor):
        def visit(self, element):
                element.label = "ConcreteVisitorB operated on this model"


model = SomeModel()

operatorA = ConcreteVisitorA()

model.accept(operatorA)

operatorB = ConcreteVisitorB()

model.accept(operatorA)

not_a_valid_type = "foo"

model.accept(not_a_valid_type)
</python>


Rui Maciel

[toc] | [prev] | [next] | [standalone]


#52046

FromRotwang <sg552@hotmail.co.uk>
Date2013-08-06 15:25 +0100
Message-ID<ktr0k6$rl$1@dont-email.me>
In reply to#52018
On 06/08/2013 11:07, Rui Maciel wrote:
> Joshua Landau wrote:
>
>> Unless you have a very good reason, don't do this [i.e. checking
>> arguments for type at runtime and raising TypeError]. It's a damn pain
>> when functions won't accept my custom types with equivalent
>> functionality -- Python's a duck-typed language and it should behave
>> like one.
>
> In that case what's the pythonic way to deal with standard cases like this
> one?
>
> <code>
> class SomeModel(object):
>          def __init__(self):
>                  self.label = "this is a label attribute"
>
>          def accept(self, visitor):
>                  visitor.visit(self)
>                  print("visited: ", self.label)
>
>
> class AbstractVisitor(object):
>          def visit(self, element):
>                  pass
>
>
> class ConcreteVisitorA(AbstractVisitor):
>          def visit(self, element):
>                  element.label = "ConcreteVisitorA operated on this model"
>
> class ConcreteVisitorB(AbstractVisitor):
>          def visit(self, element):
>                  element.label = "ConcreteVisitorB operated on this model"
>
>
> model = SomeModel()
>
> operatorA = ConcreteVisitorA()
>
> model.accept(operatorA)
>
> operatorB = ConcreteVisitorB()
>
> model.accept(operatorA)
>
> not_a_valid_type = "foo"
>
> model.accept(not_a_valid_type)
> </python>

The Pythonic way to deal with it is exactly how you deal with it above. 
When the script attempts to call model.accept(not_a_valid_type) an 
exception is raised, and the exception's traceback will tell you exactly 
what the problem was (namely that not_a_valid_type does not have a 
method called "visit"). In what way would runtime type-checking be any 
better than this? There's an obvious way in which it would be worse, 
namely that it would prevent the user from passing a custom object to 
SomeModel.accept() that has a visit() method but is not one of the types 
for which you thought to check.

[toc] | [prev] | [next] | [standalone]


#52075

FromBen Finney <ben+python@benfinney.id.au>
Date2013-08-07 08:34 +1000
Message-ID<mailman.276.1375828475.1251.python-list@python.org>
In reply to#52018
Rui Maciel <rui.maciel@gmail.com> writes:

> class AbstractVisitor(object):
>         def visit(self, element):
>                 pass

A small improvement to your code:

If you want an abstract method – that is, a method which should not be
called directly but which sub-classes should over-ride – then your
abstract method should not ‘pass’. Instead, it should ‘raise
NotImplementedError’ so this will be clear to anyone if the MRO falls
back to the abstract method.

> not_a_valid_type = "foo"
>
> model.accept(not_a_valid_type)

At this point, the ‘not_a_valid_type’ object is asked for its ‘visit’
method, and a TypeError is raised. That's good, because it informs the
person looking at the code that this object doesn't support the needed
behaviour.

This is as it's meant to be; what problem are you pointing out here?

-- 
 \      “Software patents provide one more means of controlling access |
  `\      to information. They are the tool of choice for the internet |
_o__)                                     highwayman.” —Anthony Taylor |
Ben Finney

[toc] | [prev] | [next] | [standalone]


#52012

FromChris Angelico <rosuav@gmail.com>
Date2013-08-06 10:29 +0100
Message-ID<mailman.233.1375781390.1251.python-list@python.org>
In reply to#52004
On Tue, Aug 6, 2013 at 10:01 AM, Rui Maciel <rui.maciel@gmail.com> wrote:
> It would be nice if some functions threw an error if they were passed a type
> they don't support or weren't designed to handle.  That would avoid having
> to deal with some bugs which otherwise would never happen.
>
> To avoid this sort of error, I've been testing arguments passed to some
> functions based on their type, and raising TypeError when necessariy, but
> surely there must be a better, more pythonic way to handle this issue.

def add_three_values(x,y,z):
    return x+y+z

Do you want to test these values for compatibility? Remember, you
could take a mixture of types, as most of the numeric types can safely
be added. You can also add strings, or lists, but you can't mix them.
And look! It already raises TypeError if it's given something
unsuitable:

>>> add_three_values(1,"foo",[4,6])
Traceback (most recent call last):
  File "<pyshell#28>", line 1, in <module>
    add_three_values(1,"foo",[4,6])
  File "<pyshell#25>", line 2, in add_three_values
    return x+y+z
TypeError: unsupported operand type(s) for +: 'int' and 'str'

The Pythonic way is to not care what the objects' types are, but to
simply use them.

In C++ and Java, it's usually assumed that the person writing a
function/class is different from the person writing the code that uses
it, and that each needs to be protected from each other. In Python,
it's assumed that either you're writing both halves yourself, or at
least you're happy to be aware of the implementation on the other
side. It saves a HUGE amount of trouble; for instance, abolishing
private members makes everything easier. This philosophical difference
does take some getting used to, but is so freeing. The worst it can do
is give you a longer traceback when a problem is discovered deep in
the call tree, and if your call stack takes more than a page to
display, that's code smell for another reason. (I've seen Ruby
tracebacks that are like that. I guess Ruby programmers get used to
locating the important part.)

ChrisA

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.python


csiph-web