From: MRAB on
Steven D'Aprano wrote:
> On Fri, 30 Oct 2009 15:55:04 +1100, Ben Finney wrote:
>
>> Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> writes:
>>
>>> On Thu, 29 Oct 2009 21:16:37 -0500, Tim Johnson wrote:
>>>> class formLoader():
>>> Idiomatic Python is to use CamelCase for classes.
>> Or rather: Instead of camelCase names, idiomatic Python is to use
>> TitleCase names.
>
> Thank you for the correction. I always mix up those two.
>
Wouldn't it be clearer if they were called dromedaryCase and
BactrianCase? :-)
From: Tim Golden on
MRAB wrote:
> Steven D'Aprano wrote:
>> On Fri, 30 Oct 2009 15:55:04 +1100, Ben Finney wrote:
>>
>>> Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> writes:
>>>
>>>> On Thu, 29 Oct 2009 21:16:37 -0500, Tim Johnson wrote:
>>>>> class formLoader():
>>>> Idiomatic Python is to use CamelCase for classes.
>>> Or rather: Instead of camelCase names, idiomatic Python is to use
>>> TitleCase names.
>> Thank you for the correction. I always mix up those two.
>>
> Wouldn't it be clearer if they were called dromedaryCase and
> BactrianCase? :-)

It's not often I really get a laugh out of this
mailing list, but that really made me chuckle.

Thanks :)

TJG
From: Tim Johnson on
On 2009-10-30, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au> wrote:
>
> Could you explain what problem you are trying to solve?
>
>
>> class formLoader():

Hi Steve
In a nutshell:
The 'problem' is to parse a form in such a way that tags which are to
be modified are represented as dictionaries. The 'grunt' work is
done. This class will probably grow with time.

> Idiomatic Python is to use CamelCase for classes.
Can you point me to a discussion on Idiomatic Python, CamelCase and
other matters?

> Is your intention to ensure that the only keyword arguments allowed are
> fileName, record and string?
Correct.

> Perhaps the easiest way to do that is:
>
> for k in kw:
> if k not in ('filename', 'record', 'string'):
> raise Exception() # whatever...
> setattr(self, k) = kw[k]
Understood. A better 'trick'

>> else:
>> raise AttributeError(
>
> In my opinion, AttributeError is not appropriate here. Passing an invalid
> parameter shouldn't raise the same error as failing an attribute look-up.
> That's misleading and confusing.
What error class or other approach do you recommend?

> [Aside: eight space tabs are *WAY* too big for Usenet and email. You
> should use four spaces, or even two, when posting here.]
Yikes! I just starting using vim with slrn again. Will take care of
that.

> It is idiomatic Python to use "instance attributes" to refer to
> attributes attached to instances, and "class attributes" to refer to
> those attached to classes. Talking about "class members" will confuse
> Python developers who aren't also familiar with Java or C++. (I know it
> confuses *me* -- are class members shared by all instances in a class, as
> the name implies, or are they individual to the instance, as your code
> implies?)
Thanks for that. C++ corrupted me.

> I also should point out that your trick will fail if you are using
> __slots__.
??. Will research that. Elaborate if you wish.

>> self.tokens =
> ["form","input","textarea","select","option","form"]
<....>
>
> Is any of that relevant to the trick you are asking for comments for? If
> not, why is it here?
It was there to illustrate my edification of the usage of self.__dict__

>> I'd welcome comments - such as any other applications.
>
> Personally, I don't like it. The method signature makes it impossible to
> tell what arguments are excepted, and it forces me to use keywords even
> if I'd prefer to use positional arguments. I prefer to let the
> interpreter check the arguments for me:

Using your tuple example would clarify things. The method signature
then becomes the tuple. I.E

#<steve sayeth>
if k not in ('filename', 'record', 'string'):
# handle here

If the class grows - and I expect it will - I'd prefer to stick with
the keywords approach. That approach also allows me to use a
dictionary to initialize the object.

Thanks for the input. Very helpful.
- and always a newbie -
--
Tim
tim(a)johnsons-web.com
http://www.akwebsoft.com
From: Steven D'Aprano on
On Fri, 30 Oct 2009 11:16:29 -0500, Tim Johnson wrote:

> On 2009-10-30, Steven D'Aprano <steve(a)REMOVE-THIS-cybersource.com.au>
> wrote:
>>
>> Could you explain what problem you are trying to solve?
>>
>>
>>> class formLoader():
>
> Hi Steve
> In a nutshell:
> The 'problem' is to parse a form in such a way that tags which are to
> be modified are represented as dictionaries. The 'grunt' work is done.
> This class will probably grow with time.

The standard way of doing this is to list the arguments as parameters,
together with their defaults:

def __init__(self, filename=None, record=None, string=None):
...


Then Python will do the error checking for your, and raise an exception
if the caller passes an unexpected argument. Can you explain why this
isn't enough for your needs, and you need to do something else?


>> Idiomatic Python is to use CamelCase for classes.
> Can you point me to a discussion on Idiomatic Python, CamelCase and
> other matters?

See PEP 8:

http://www.python.org/dev/peps/pep-0008/



>> In my opinion, AttributeError is not appropriate here. Passing an
>> invalid parameter shouldn't raise the same error as failing an
>> attribute look-up. That's misleading and confusing.
>
> What error class or other approach do you recommend?

Unless you have a good reason for doing something different, do what
Python built-ins do:

>>> int('123', parrot=16)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'parrot' is an invalid keyword argument for this function


>> I also should point out that your trick will fail if you are using
>> __slots__.
> ??. Will research that. Elaborate if you wish.

__slots__ are an optimization for making objects smaller than normal if
you have many millions of them:

http://docs.python.org/reference/datamodel.html#slots


> If the class grows - and I expect it will - I'd prefer to stick with
> the keywords approach. That approach also allows me to use a
> dictionary to initialize the object.

You can still do that with named parameters.


>>> class Parrot:
.... def __init__(self, name='Polly', colour='blue',
.... breed='Norwegian'):
.... self.name = name
.... self.colour = colour
.... self.breed = breed
.... def speak(self):
.... print "%s the %s %s says 'Give us a kiss!'" % (
.... self.name, self.colour, self.breed)
....
>>> p = Parrot("Sparky", 'white', "Cockatoo")
>>> p.speak()
Sparky the white Cockatoo says 'Give us a kiss!'
>>>
>>> data = dict(colour='red', name='Fred', foo=1)
>>> p = Parrot(**data) # raise an error with bad input
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: __init__() got an unexpected keyword argument 'foo'
>>>
>>> del data['foo'] # fix the bad input
>>> p = Parrot(**data)
>>> p.speak()
Fred the red Norwegian says 'Give us a kiss!'


--
Steven
From: Hendrik van Rooyen on
On Friday, 30 October 2009 17:28:47 MRAB wrote:

> Wouldn't it be clearer if they were called dromedaryCase and
> BactrianCase? :-)

Ogden Nash:

The Camel has a single hump-
The Dromedary, two;
Or the other way around-
I'm never sure. - Are You?

- Hendrik