Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #51978 > unrolled thread
| Started by | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| First post | 2013-08-05 21:46 +0100 |
| Last post | 2013-08-06 15:05 +0000 |
| Articles | 20 on this page of 29 — 15 participants |
Back to article view | Back to comp.lang.python
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 →
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-08-05 21:46 +0100 |
| Subject | Newbie: 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]
| From | Gary Herron <gary.herron@islandtraining.com> |
|---|---|
| Date | 2013-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]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Steven D'Aprano <steve@pearwood.info> |
|---|---|
| Date | 2013-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]
| From | Joshua Landau <joshua@landau.ws> |
|---|---|
| Date | 2013-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]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Burak Arslan <burak.arslan@arskom.com.tr> |
|---|---|
| Date | 2013-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]
| From | Antoon Pardon <antoon.pardon@rece.vub.ac.be> |
|---|---|
| Date | 2013-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-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]
| From | "Eric S. Johansson" <esj@harvee.org> |
|---|---|
| Date | 2013-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2013-08-07 08:23 +1000 |
| Subject | Easier 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]
| From | Ian Kelly <ian.g.kelly@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2013-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]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Joshua Landau <joshua@landau.ws> |
|---|---|
| Date | 2013-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]
| From | Rui Maciel <rui.maciel@gmail.com> |
|---|---|
| Date | 2013-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]
| From | Rotwang <sg552@hotmail.co.uk> |
|---|---|
| Date | 2013-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]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2013-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]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-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