FAQ
As telling in the subject,because "list" and "tuple" aren't functions,they are types.Is that right?

Search Discussions

  • Steven D'Aprano at Jul 15, 2011 at 1:32 am

    Inside wrote:

    As telling in the subject,because "list" and "tuple" aren't functions,they
    are types.Is that right?
    Yes they are types. But they can still be used as functions. Does it matter?


    --
    Steven
  • Ben Finney at Jul 15, 2011 at 1:51 am

    Steven D'Aprano <steve+comp.lang.python at pearwood.info> writes:

    Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they
    are types.Is that right?
    Yes they are types. But they can still be used as functions. Does it matter?
    As a newcomer to the documentation I looked fruitlessly in the table of
    contents for a section that would contain the built-in types. ?Built-in
    functions? was eliminated for the reason the OP states.

    I think it matters. (But I haven't proposed a documentation patch for it.)

    --
    \ ?But Marge, what if we chose the wrong religion? Each week we |
    `\ just make God madder and madder.? ?Homer, _The Simpsons_ |
    _o__) |
    Ben Finney
  • Terry Reedy at Jul 15, 2011 at 3:00 am

    On 7/14/2011 9:51 PM, Ben Finney wrote:
    Steven D'Aprano<steve+comp.lang.python at pearwood.info> writes:
    Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they
    are types.Is that right?
    At one time (before 2.2), they were functions and not classes.
    Yes they are types. But they can still be used as functions. Does it matter?
    As a newcomer to the documentation I looked fruitlessly in the table of
    contents for a section that would contain the built-in types. ?Built-in
    functions? was eliminated for the reason the OP states.

    I think it matters. (But I haven't proposed a documentation patch for it.)
    I once proposed, I believe on the tracker, that 'built-in functions' be
    expanded to 'built-in function and classes'. That was rejected on the
    basis that people would then expect the full class documentation that is
    in the 'built-in types' section (which could now be called the
    built-isssn classes section.

    A more exact title would be 'built-in callables', but that would be even
    less helpful to newcomers. Callables are functions in the generic sense.

    In any case, the new index makes it easy to see what is in that chapter.

    --
    Terry Jan Reedy
  • Stefan Behnel at Jul 15, 2011 at 9:03 pm

    Terry Reedy, 15.07.2011 05:00:
    On 7/14/2011 9:51 PM, Ben Finney wrote:
    Steven D'Aprano writes:
    Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they
    are types.Is that right?
    At one time (before 2.2), they were functions and not classes.
    They are still functions in the sense that you can call them (with or
    without arguments) and get a result back. The exact distinction can be
    considered an implementation detail in most contexts.

    There are even extreme cases that render the distinction completely
    useless. Think of type(), for example. In its exceedingly most common use
    case, it does *not* create a type, even if it's a call to a type
    constructor. Something similar applies to a no-args call to tuple(), which
    does not create a new object in CPython, but only returns a new reference
    to a singleton.

    Types in Python are allowed to do these things, so it's not always
    meaningful to distinguish between typeX() being a call to a type or a function.

    Yes they are types. But they can still be used as functions. Does it
    matter?
    As a newcomer to the documentation I looked fruitlessly in the table of
    contents for a section that would contain the built-in types. ?Built-in
    functions? was eliminated for the reason the OP states.

    I think it matters. (But I haven't proposed a documentation patch for it.)
    I once proposed, I believe on the tracker, that 'built-in functions' be
    expanded to 'built-in function and classes'. That was rejected on the basis
    that people would then expect the full class documentation that is in the
    'built-in types' section (which could now be called the built-isssn classes
    section.

    A more exact title would be 'built-in callables', but that would be even
    less helpful to newcomers. Callables are functions in the generic sense.
    I think "function" is about the best "expected" and "newcomer-friendly"
    name one can give to a "callable", especially in the context of a
    duck-typed, protocol-oriented language like Python. The section title in
    question describes perfectly its contents.

    It's a different question if a separate section like "here's a list of
    reference to the descriptions of types that Python provides in its
    builtins" is required. But I think we have that already.

    In any case, the new index makes it easy to see what is in that chapter.
    Agreed.

    Stefan
  • Chris Angelico at Jul 15, 2011 at 6:24 am

    On Fri, Jul 15, 2011 at 11:32 AM, Steven D'Aprano wrote:
    Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they
    are types.Is that right?
    Yes they are types. But they can still be used as functions. Does it matter?
    Python is duck-typed, even in its documentation. If Python describes
    something as a function, it means it can be used in place of func in
    here:

    result = func(arg1, arg2, arg3)

    It might be something created with def (a "classic" function). It
    might be something created with lambda. It might be an object with a
    __call__ method. It might be a type.
    class foo:
    def __call__(self):
    return lambda: print("asdf")
    bar=foo()
    quux=bar()
    quux()
    asdf

    How many functions are defined here?

    Chris Angelico
  • Rantingrick at Jul 15, 2011 at 1:36 am

    On Jul 14, 8:21?pm, Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they are types.Is that right?
    You wanna see some warts in the docs. Okay, try to use the search box
    to find list, dict, or tuple and see what happens...

    http://docs.python.org/

    Search: [ list ]

    PyFloat_ClearFreeList (cfunction, in Floating Point Objects)
    PyInt_ClearFreeList (cfunction, in Plain Integer Objects)
    PyListObject (ctype, in List Objects)
    PyList_Append (cfunction, in List Objects)
    PyList_AsTuple (cfunction, in List Objects)
    PyList_Check (cfunction, in List Objects)
    PyList_CheckExact (cfunction, in List Objects)
    PyList_GET_ITEM (cfunction, in List Objects)
    PyList_GET_SIZE (cfunction, in List Objects)
    PyList_GetItem (cfunction, in List Objects)
    PyList_GetSlice (cfunction, in List Objects)
    PyList_Insert (cfunction, in List Objects)
    PyList_New (cfunction, in List Objects)
    PyList_Reverse (cfunction, in List Objects)
    PyList_SET_ITEM (cfunction, in List Objects)
    PyList_SetItem (cfunction, in List Objects)
    PyList_SetSlice (cfunction, in List Objects)
    PyList_Size (cfunction, in List Objects)
    PyList_Sort (cfunction, in List Objects)
    PyList_Type (cvar, in List Objects)
    PyMethod_ClearFreeList (cfunction, in Method Objects)

    [ snip: mile long list with no LIST info to be found! ]

    Hey don't get me wrong, the python docs are great; as long as you know
    where to find what you're looking for.
  • Corey Richardson at Jul 15, 2011 at 2:01 am

    Excerpts from rantingrick's message of Thu Jul 14 21:36:15 -0400 2011:
    On Jul 14, 8:21pm, Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they are types.Is that right?
    You wanna see some warts in the docs. Okay, try to use the search box
    to find list, dict, or tuple and see what happens...

    http://docs.python.org/

    Search: [ list ]

    PyMethod_ClearFreeList (cfunction, in Method Objects)

    [ snip: mile long list with no LIST info to be found! ]

    Hey don't get me wrong, the python docs are great; as long as you know
    where to find what you're looking for.
    I agree, having the stuff from the C API docs appear in the search isn't
    very useful. Perhaps the search should be redesigned with stuff like that
    in mind? (Or maybe the search is more advanced than I use it). They aren't
    exactly warts, it's useful information, but in the common case they probably
    aren't desired (I always use Google to search around the python docs).

    Not to mention that the search is slooowwww. It's plenty fast on my local
    download, but I haven't actually looked at the search to see what it does
    and how.
    --
    Corey Richardson
    "Those who deny freedom to others, deserve it not for themselves"
    -- Abraham Lincoln
    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: signature.asc
    Type: application/pgp-signature
    Size: 490 bytes
    Desc: not available
    URL: <http://mail.python.org/pipermail/python-list/attachments/20110714/9cec45ed/attachment-0001.pgp>
  • Inside at Jul 15, 2011 at 2:58 am
    Hey guy,thx for you feedback first.

    But I can't follow your opinion.Why?because of the list & tuple are placed at built-in function,so before I type 'list' unintentionally on the pyshell and it show me "<type 'list'>", I never know that the name 'list' is a type,I used to consider it's a function to produce 'list' type.

    so,after I figure out this matter,I have to change all my code "assert isinstance(someobj, (type([]), type((0, ))))" to "assert isinstance(someobj, (list, tuple))",that's not a funny job.

    I hope that I can stay in the Python abstract layer to solve problem(although go to the C API is OK but I don't want to),I'm going to trust what the doc telling me,so I hope the doc is exact enough.And the doc in the distribution maybe the most popular one.

    @Steven D'Aprano,yes they can be used as function,but they aren't function and shouldn't confuse newcomers by this.
  • Ben Finney at Jul 15, 2011 at 3:47 am

    Inside <fancheyujian at gmail.com> writes:

    But I can't follow your opinion.Why?because of the list & tuple are
    placed at built-in function,so before I type 'list' unintentionally on
    the pyshell and it show me "<type 'list'>", I never know that the name
    'list' is a type,I used to consider it's a function to produce 'list'
    type.
    That's the kind of fundamental knowledge that one gains by working
    through the Python tutorial <URL:http://docs.python.org/tutorial/>. The
    library reference is not the place for teaching that information.
    so,after I figure out this matter,I have to change all my code "assert
    isinstance(someobj, (type([]), type((0, ))))" to "assert
    isinstance(someobj, (list, tuple))",that's not a funny job.
    If you think you need to do such assertions, that's a code smell; it's
    rare to need that kind of assertion and should only be done with good
    reason since it breaks polymorphism. Why are you doing it?
    I hope that I can stay in the Python abstract layer to solve
    problem(although go to the C API is OK but I don't want to),I'm going
    to trust what the doc telling me,so I hope the doc is exact enough.And
    the doc in the distribution maybe the most popular one.
    Including the tutorial, so now you have your homework to do :-)
    @Steven D'Aprano,yes they can be used as function,but they aren't
    function and shouldn't confuse newcomers by this.
    Agreed; however, it seems reasonable people can disagree on how much
    that matters. I think it should be fixed, but not enough to push for it.

    --
    \ ?Leave nothing to chance. Overlook nothing. Combine |
    `\ contradictory observations. Allow yourself enough time.? |
    _o__) ?Hippocrates |
    Ben Finney
  • Inside at Jul 15, 2011 at 7:53 pm
    Why I use assertion,please check this code:
    """
    class User(object):pass

    class Student(User):pass

    class Professional(User):pass

    def add(user):
    assert(user, User)

    def add(users):
    assert(users, (tuple, list))
    #If necessary I'll also check every obj in the sequence to see whether it's a User.
    """

    I just follow some coding rules of me:
    1. Controlling "input" strictly.
    2. In a function keep doubting on its parameters until they're checked.
    3. Let potential errors raise as early as possible.
  • Ben Finney at Jul 15, 2011 at 11:24 pm

    Inside <fancheyujian at gmail.com> writes:

    I just follow some coding rules of me:
    1. Controlling "input" strictly.
    Asserting that the input is of a specific type is too strict. Does your
    code work if the input is not a list or tuple?

    I suspect strongly that the answer is yes, it works fine with any
    sequence, even ones that don't inherit from ?list? nor ?tuple?. It will
    probably work with any sequence; it amy even work with any iterable.

    Instead of insisting on specific types, you should support polymorphism:
    expect *behaviour* and allow any input that exhibits that behaviour.

    This is known as ?duck typing?: you don't need to care whether it's a
    duck, you just need to know whether it walks like a duck and quacks like
    a duck. If it turns out to be a goose, but that won't affect your code,
    you shouldn't care.
    2. In a function keep doubting on its parameters until they're
    checked.
    This is called ?Look Before You Leap? (LBYL) programming, and is
    generally considered not Pythonic.

    Rather, ?it is Easier to Ask Forgiveness than Permission? (EAFP) is the
    Python programming style, and fits with its widespread reliance on
    polymorphism (including ?duck typing?).

    Accept the input, and use it as though it has the correct behaviour ?
    without regard to what type is providing that behaviour.

    If it doesn't have the expected behaviour, either the type will complain
    (raising an exception that you can handle at an appropriate level in
    your code), or your comprehensive unit tests will detect the
    misbehaviour.

    If you don't have comprehensive unit tests, that's where you should put
    your effort of strict interface testing. Not type assertions in the
    application code.
    3. Let potential errors raise as early as possible.
    That is good practice. But you should not compromise polymorphism to
    that.

    --
    \ ?The whole area of [treating source code as intellectual |
    `\ property] is almost assuring a customer that you are not going |
    _o__) to do any innovation in the future.? ?Gary Barnett |
    Ben Finney
  • Steven D'Aprano at Jul 16, 2011 at 2:47 am
    Ben Finney wrote:

    [...snip explanation of duck-typing...]
    If you don't have comprehensive unit tests, that's where you should put
    your effort of strict interface testing. Not type assertions in the
    application code.
    I agree with everything Ben said here, but he has missed something even more
    fundamental.

    Type *checking* breaks duck-typing. Type *assertions* are even worse,
    because assertions aren't guaranteed to run. If you are using "assert
    isinstance(...)" to validate input data, there are situations where your
    validation step does not happen at all, and your code may just break in the
    least convenient way. So not only are you validating the wrong way, but
    sometimes you don't validate at all!

    Assertions are for testing internal program logic, not for validation.

    (I don't even like using assert for testing. How do you test your code with
    assertions turned off if you use assert for testing?)



    --
    Steven
  • Chris Rebert at Jul 16, 2011 at 5:02 am

    On Fri, Jul 15, 2011 at 7:47 PM, Steven D'Aprano wrote:
    <snip>
    Assertions are for testing internal program logic, not for validation.

    (I don't even like using assert for testing. How do you test your code with
    assertions turned off if you use assert for testing?)
    I would think that would only matter if either the asserted
    expressions caused side-effects or there was nontrivial logic in the
    AssertionError handler, which would indicate a rather screwy codebase
    and point to a possible PEBKAC issue that testing cannot hope to
    remedy.

    Cheers,
    Chris
  • Steven D'Aprano at Jul 16, 2011 at 6:33 am

    Chris Rebert wrote:

    On Fri, Jul 15, 2011 at 7:47 PM, Steven D'Aprano
    wrote:
    <snip>
    Assertions are for testing internal program logic, not for validation.

    (I don't even like using assert for testing. How do you test your code
    with assertions turned off if you use assert for testing?)
    I would think that would only matter if either the asserted
    expressions caused side-effects or there was nontrivial logic in the
    AssertionError handler, which would indicate a rather screwy codebase
    and point to a possible PEBKAC issue that testing cannot hope to
    remedy.
    I'm not sure I follow you there...

    For any piece of code, I claim that we should test both with and without
    the -O switch. If I don't test it with -O, how do I know it works correctly
    when run with -O? Even if I don't use assert yourself, I don't know if the
    code I call uses assert badly and therefore is affected by -O.

    (I recently discovered that ElementTree, in the Python standard library,
    uses assert for data validation in at least some Python versions.)

    Besides, I don't know what -O does, apart from disabling assertions. Maybe
    nothing else. Maybe lots of things. It may change from version to version.
    Who knows? Whatever it does, it *shouldn't* change the semantics of my
    code, but it *could*, hence I better test it to find out if anything has
    changed.

    So are we agreed that it is wise to test code both with and without the -O
    switch?

    But here's the problem... the -O switch is global, and not module specific.
    So if your test suite looks like this:

    import mymodule
    assert hasattr(mymodule, "__all__")
    assert isinstance(mymodule.__version__, str)
    assert mymodule.count_spam("spam spam spam") == 3
    a, b, c = mymodule.aardvark(42)
    assert a < b < c

    when running with -0, all those tests LITERALLY go away and you're left with
    a significantly smaller test suite:

    import mymodule
    a, b, c = mymodule.aardvark(42)

    which is hardly better than no test at all.



    --
    Steven
  • Chris Angelico at Jul 15, 2011 at 11:27 pm

    On Sat, Jul 16, 2011 at 5:53 AM, Inside wrote:
    def add(users):
    ? ?assert(users, (tuple, list))
    ? ?#If necessary I'll also check every obj in the sequence to see whether it's a User.

    I just follow some coding rules of me:
    1. Controlling "input" strictly.
    2. In a function keep doubting on its parameters until they're checked.
    3. Let potential errors raise as early as possible.
    What you're doing there is writing code in Python, not writing Python code.

    To be more Pythonic, your code should actually stop caring about
    whether something is-a User, and instead simply care about whether or
    not it can be treated as a User. (And for Travaglia fans, yes, a User
    object WILL have an abuse() method.)

    Instead of asserting that the parameter is a User, just add it
    cheerfully to your list, and then when you iterate over the list and
    call some method on each one, you'll get an exception if one of them
    doesn't have that method.

    This allows a huge enhancement to polymorphism, in that you no longer
    need to worry about what your pointers are; in C++, you can run over a
    list of users and ask if they're all Students, but then you need to
    cast all those pointers if you're going to then ask them all what
    subjects they're studying. In Python, all you do is ask your list of
    objects what subjects they're studying - all the students will
    respond, and anything that doesn't know what "studying" is will throw
    an exception.

    The analogy with reality breaks down a bit here. I've seen plenty of
    students with no idea of what it means to study. But Python can handle
    that too - just 'del' the method in the subclass.

    ChrisA
  • Ben Finney at Jul 16, 2011 at 12:04 am

    Chris Angelico <rosuav at gmail.com> writes:

    The analogy with reality breaks down a bit here. I've seen plenty of
    students with no idea of what it means to study. But Python can handle
    that too - just 'del' the method in the subclass.
    No, please don't. That would break the Liskov substitution principle
    <URL:https://secure.wikimedia.org/wikipedia/en/wiki/Liskov_substitution_principle>.

    By inheriting from a type that provides a method, you're promising that
    you will implement at least as much behaviour as the parent. If that
    includes a ?study? method, then your subclass must also implement (or
    inherit) that method.

    Code can then be written to expect that, so long as the object inherits
    from Student, it will at least have the same minimum level of behaviour
    that a Student has.

    If you inherit from Student, but delete the ?study? method, you would
    break any code which assumes any Student has a ?study? method ?
    something that was explicitly promised in the API of Student.

    Since you are advocating calling people students when they don't study,
    it sounds instead like you want a different set of promises:

    class Student(Person):
    """ An enrolled student at this institution. """

    def study(self, subject):
    raise NotImplementedError

    class LectureAttendee(Student):
    """ Someone who comes to lectures. """

    def attend(self, lecture):
    pass

    class StudentWhoActuallyStudies(Student):
    """ A student who actually is capable of studying. """

    def study(self, subject):
    """ Actually apply my knowledge of how to study. """

    alice = StudentWhoActuallyStudies("Alice")
    bob = Student("Bob")

    alice.study("chemistry") # actual study
    bob.study("garden gnome painting") # not implemented!

    Now both Alice and Bob fulfil the technical requirements of a student at
    the institution, but the expectations of study capability are clear.

    Any code using this implementation of Student knows that, if they want a
    student who actually studies, they'd better ask for a more specific
    type.

    See? We can have overstretched analogies *and* remain within the Liskov
    substitution principle.

    --
    \ Eccles: ?I just saw the Earth through the clouds!? Lew: ?Did |
    `\ it look round?? Eccles: ?Yes, but I don't think it saw me.? |
    _o__) ?The Goon Show, _Wings Over Dagenham_ |
    Ben Finney
  • Chris Angelico at Jul 16, 2011 at 12:17 am

    On Sat, Jul 16, 2011 at 10:04 AM, Ben Finney wrote:
    ? ? ? ?def study(self, subject):
    ? ? ? ? ? ?raise NotImplementedError

    See? We can have overstretched analogies *and* remain within the Liskov
    substitution principle.
    Hehe! Of course I was speaking utterly in jest, but this raises
    (sorry, never could resist a bad pun) another question: What if the
    base class implemented study(), and then LazyStudent subclasses
    Student but makes study() raise NotImpl? Would that break things? In a
    sense, it breaks the whole "this is a student so it should act like a
    student" rule. Suppose it raised UtterApathyError instead - does that
    break the LSP?

    Chris A
    PS. The world's first horseless signature... trapped in the air!
  • Ben Finney at Jul 16, 2011 at 1:47 am

    Chris Angelico <rosuav at gmail.com> writes:

    What if the base class implemented study(), and then LazyStudent
    subclasses Student but makes study() raise NotImpl? Would that break
    things? In a sense, it breaks the whole "this is a student so it
    should act like a student" rule.
    That would break the Liskov substitution principle, yes. Anything that
    asks for a Student instance should receive an object that can do at
    least everything Student can do.

    If you want to implement something that can't do some of the things
    Student can do, the Liskov substitution principle says you are
    implementing some object that does *not* inherit from Student.

    This fits nicely with the principle (whose name I'm currently too lazy
    to look up) that says you should only use inheritance for ?IS-A?
    relationships. If LazyStudent can't do everything Student can do, then
    it's false to say LazyStudent IS-A Student, so using inheritance for
    that would be to state something in code which isn't true.
    Suppose it raised UtterApathyError instead - does that break the LSP?
    Probably, yes. Your point is taken though: it's not something that can
    be drawn along a bright line.

    --
    \ ?Those are my principles. If you don't like them I have |
    `\ others.? ?Groucho Marx |
    _o__) |
    Ben Finney
  • Steven D'Aprano at Jul 16, 2011 at 4:06 am

    Inside wrote:

    Why I use assertion,please check this code:
    """
    class User(object):pass

    class Student(User):pass

    class Professional(User):pass

    def add(user):
    assert(user, User)
    This does not do what you think it does. All it does is, in some Python
    versions, print

    SyntaxWarning: assertion is always true, perhaps remove parentheses?

    In other Python versions, it is a no-op: it does nothing.

    Perhaps you meant this?

    assert isinstance(user, User)

    Ben has already posted why isinstance type-checking should usually be
    avoided in favour of duck-typing ("if it looks like a duck, and sounds like
    a duck, and swims like a duck, it might as well be a duck"). But let's
    suppose you have good reason for sticking to an explicit type-check. The
    problem now is with the assert! Assertions are not guaranteed to run. The
    caller can turn them off by running Python with the -O (optimize) switch.

    Another problem: AssertionError is the wrong sort of exception to raise on
    bad arguments. It should normally be TypeError or ValueError, or some other
    more specific exception, with a useful error message.

    Assertions are for testing your own program logic, not for validating input.
    For example, in one of my own libraries, I have this piece of code:

    data = _countiter(data)
    assert data.count == 0
    total = sum(data)
    n = data.count
    assert n >= 0
    # much later on...
    return math.sqrt(value/n)


    _countiter is a wrapper that keeps track of how many items have been
    iterated over. I take an arbitrary iterator, wrap it, sum the values, then
    check that the number of items is not a negative number. If it is, that's a
    bug in my program logic, and I should find out as soon as possible, not
    much later on when I try to take the square root of it.

    Assertions should be rare, and never used for testing arguments (except,
    maybe, for purely internal functions that only get called by your own
    functions, never by the caller). If the caller ever sees an AssertionError
    generated by your code, that is a bug in your code.



    --
    Steven
  • Inside at Jul 16, 2011 at 5:35 am

    Perhaps you meant this?

    assert isinstance(user, User)
    Yes I meant this,sorry,my mistake.

    ------------------------

    Thx for your and Ben's feedbacks first,it's appreciated.
    your points is taken by me,but I want to make my opinion more clearly.

    The assertion is JUST show to my function callers during development,warning that "I want a list/tuple,not some other objects"(BTW, your practice of wrapping arguments to iter is good,I'll take this to improve my code,thx again.).And assertion's off when running Python with the -O (optimize) switch is what I expect,it isn't necessary in production code.Argument validation is done by constuctor of object which I used in assertion.

    I also have a few words about duck-typing.Duck-typing is good,but how about if I offer a convenient way to my function user by producing or changing what he want to pass me to a *real* duck?Is that more explicit to my user?

    Anyway,I'll look at my principles which may need some changes or improvements.
  • Inside at Jul 16, 2011 at 5:40 am
    Supplement:
    The assertion will not be handled anyway.
    I want AssertionError raise as early as possible.(mentinoed before)
  • Corey Richardson at Jul 16, 2011 at 7:50 am

    Excerpts from Inside's message of Sat Jul 16 01:40:21 -0400 2011:
    Supplement:
    The assertion will not be handled anyway.
    I want AssertionError raise as early as possible.(mentinoed before)
    An AssertionError is pretty useless, there are much better exceptions
    that you could (and should!) use, depending on the context. If you
    need a sequence, just use it like it is. If it's not a sequence a
    TypeError will be raised anyway:
    class Foo(object): pass
    ...
    f = Foo()
    for i in f: pass
    ...
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    TypeError: 'Foo' object is not iterable
    >>>

    Which is tons more useful than
    assert isinstance(f, (list, tuple))
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AssertionError
    >>>
    --
    Corey Richardson
    "Those who deny freedom to others, deserve it not for themselves"
    -- Abraham Lincoln
    -------------- next part --------------
    A non-text attachment was scrubbed...
    Name: signature.asc
    Type: application/pgp-signature
    Size: 490 bytes
    Desc: not available
    URL: <http://mail.python.org/pipermail/python-list/attachments/20110716/7482f0da/attachment.pgp>
  • Bruno Desthuilliers at Jul 15, 2011 at 7:27 am

    On Jul 15, 4:58?am, Inside wrote:
    Hey guy,thx for you feedback first.

    But I can't follow your opinion.Why?because of the list & tuple are placed at built-in function,so before I type 'list' unintentionally on the pyshell and it show me "<type 'list'>", I never know that the name 'list' is a type,I used to consider it's a function to produce 'list' type.

    so,after I figure out this matter,I have to change all my code "assert isinstance(someobj, (type([]), type((0, ))))" to "assert isinstance(someobj, (list, tuple))",that's not a funny job.
    Are you sure you need such assertions in your code ?
  • Bruno Desthuilliers at Jul 15, 2011 at 7:29 am

    On Jul 15, 9:27?am, "bruno.desthuilli... at gmail.com" wrote:
    On Jul 15, 4:58?am, Inside wrote:

    Hey guy,thx for you feedback first.
    But I can't follow your opinion.Why?because of the list & tuple are placed at built-in function,so before I type 'list' unintentionally on the pyshell and it show me "<type 'list'>", I never know that the name 'list' is a type,I used to consider it's a function to produce 'list' type.
    so,after I figure out this matter,I have to change all my code "assert isinstance(someobj, (type([]), type((0, ))))" to "assert isinstance(someobj, (list, tuple))",that's not a funny job.
    Are you sure you need such assertions in your code ?
    Sorry, Ben already mentionned this. Need more coffee obviously :-/
  • Carl Banks at Jul 15, 2011 at 7:36 am

    On Thursday, July 14, 2011 8:00:16 PM UTC-7, Terry Reedy wrote:
    I once proposed, I believe on the tracker, that 'built-in functions' be
    expanded to 'built-in function and classes'. That was rejected on the
    basis that people would then expect the full class documentation that is
    in the 'built-in types' section (which could now be called the
    built-isssn classes section.
    Built in functions and contructors?


    Carl Banks
  • Raymond Hettinger at Jul 19, 2011 at 6:52 am

    On Jul 14, 6:21?pm, Inside wrote:
    As telling in the subject,because "list" and "tuple" aren't functions,they are types.Is that right?
    list() and tuple() are in the right place in the documentation because
    they would be harder to find if listed elsewhere. Tools like str(),
    int(), list(), tuple() etc tend to be used like functions, so the
    current location in the docs is where they have been for years.

    A simple fact of documentation that is that tools don't always fall
    cleanly into distinct categories. Accordingly, the Library Reference
    includes str,int,list,tuple, etc in both Section 2 for builtin
    functions and Section 5 for builtin types.

    'nuff said,


    Raymond
  • Terry Reedy at Jul 19, 2011 at 4:31 pm

    On 7/19/2011 2:52 AM, Raymond Hettinger wrote:
    On Jul 14, 6:21 pm, Insidewrote:
    As telling in the subject,because "list" and "tuple" aren't
    functions,they are types.Is that right?
    They are not instances of a class whose definition name includes the
    word 'Function'. They *are* things that can be called with the call
    operator () (because they have __call__ methods) and that, when called,
    map input objects to output objects. That is the mathematical notion of
    a function. It is also one thing that makes classes different from
    modules, which cannot be called. Classes *also* have other behaviors
    that functions do not, but that does not make them non-functions. Doing
    things besides programming Python does not make one not a Python programmer.
    list() and tuple() are in the right place in the documentation
    because they would be harder to find if listed elsewhere. Tools
    like str(), int(), list(), tuple() etc tend to be used like
    functions, so the current location in the docs is where they have
    been for years.
    The location of anything (that is not missing from the index, which is a
    bug) is easily discovered using the index.
    A simple fact of documentation that is that tools don't always fall
    cleanly into distinct categories.
    This is more like a fact of life above the atomic level. As the number
    of things classified grows, most classifications tend to become
    controversial.
    Accordingly, the Library Reference
    includes str,int,list,tuple, etc in both Section 2 for
    builtin functions and Section 5 for builtin types.
    Chapter 5 is mostly about the behavior of built-in class instances. For
    some classes, like range, instances only come from class calls and the
    behavior of instances is intimately tied to the constructor arguments.
    Having the constructor described in C.5 might be useful. For others,
    like int, instances come from many sources and the behavior of instances
    only depends on the resulting value and not the source. Ints can come
    from literals, computation, and int calls with int, other number, or
    string objects. The allowed argument issues for int calls are quite
    separate from using int, so it really belongs in C.2.

    I agree that it is best to list all named built-in classes in C.2 with
    appropriates links to C.5 (and v.v.). There is a current tracker issue
    to add the few links that are missing from C.2 to C.5.

    --
    Terry Jan Reedy
  • Stefan Behnel at Jul 20, 2011 at 6:21 am

    Terry Reedy, 19.07.2011 18:31:
    Chapter 5 is mostly about the behavior of built-in class instances. For
    some classes, like range, instances only come from class calls and the
    behavior of instances is intimately tied to the constructor arguments.
    Having the constructor described in C.5 might be useful.
    I strongly disagree. To me, range() being implemented as a class or
    function is a clear implementation detail that is of no importance to
    virtually all use cases. It's only ever used as a function that returns a
    list (in Py2) or something iterable (in Py3). Whether that "iterable" is of
    type "range" or not is irrelevant. Even in Py2, it could return a subtype
    of list, and would still fulfil its interface.

    So, IMO, it makes no sense to have range() described in the builtin types
    section. It would rather be confusing. It's perfectly correct and
    sufficient to describe it in the builtin functions section.

    Remember that Python is duck-typed. It makes no difference if you call a
    function that returns a new instance of a type, or the type itself to
    return an instance of itself (or something completely different, if it
    wants to).

    The distinction between types and functions is blurred in Python, and
    that's a good thing. Just look at the itertools module. Some of the
    "functions" are implemented as functions, some are implemented as types,
    and some are functions that delegate to a type. But they all have the same
    interface, which makes them easy to understand as a whole and which keeps
    the implementation details out of the way.

    Stefan
  • Terry Reedy at Jul 20, 2011 at 8:53 pm

    On 7/20/2011 2:21 AM, Stefan Behnel wrote:
    Terry Reedy, 19.07.2011 18:31:
    Chapter 5 is mostly about the behavior of built-in class instances. For
    some classes, like range, instances only come from class calls and the
    behavior of instances is intimately tied to the constructor arguments.
    Having the constructor described in C.5 might be useful.
    I strongly disagree.
    Wow. Strongly disagreeing with a mild statement like 'might be useful'
    is really strong. But let me explain (using slice rather than range).
    Three of the four non-special attributes of the slice objects produced
    by the slice() function are the three arguments of the function. (The
    fourth is an obscure method.) So the function and its result object are
    closely tied together, and unusually so. Hence it *might* be useful to
    discuss that particular pair together, especially since both are used
    rarely and always together. This is a rather minimal concession to the OP.

    But the overall thrust and conclusion of both that post of mine and the
    previous one is that 'function' in 'built-in functions' is best
    understood generically as including objects of type 'type' as well as
    objects of 'builtin_function_or_method' (and any other built-in callable
    if there happen to be any). So the rest of your post is strong agreement
    with what I have said since the beginning of the thread.

    What one needs to know about range is that it produces a non-iterator
    re-iterable virtual sequence object that supports a basic subset of the
    sequence operations. The function belongs in the function chapter and
    the sequence object in the sequence section of the classes chapter.

    The OP's point makes more sense in the context of other languages that
    make an artificial distinction between functions and constructors and
    require that the latter be preceded by keyword new. I prefer Python's
    uniformity.

    --
    Terry Jan Reedy

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedJul 15, '11 at 1:21a
activeJul 20, '11 at 8:53p
posts30
users12
websitepython.org

People

Translate

site design / logo © 2022 Grokbase