Re: Using eval, or something like it...

2008-11-24 Thread Gabriel Genellina

En Fri, 21 Nov 2008 13:58:59 -0200, r0g <[EMAIL PROTECTED]>
escribió:


I hadn't really appreciated the consequences of this till now though
e.g. that an instance might do a = a + 1 without affecting it's siblings
but that b.append("fish") would affect b for everyone. I don't know if I
will find any uses for that kind of behaviour but it doesn't hurt to
understand it :-)

Isn't Python's behaviour a little peculiar in this respect though,
compared to classes in other languages? i.e. Are instances in other OO
languages like Smalltalk, C++ fully independent copies or do their
attribute names just point to one common object until reassigned like in
python? (Or have I still not it at all?!)


In C++, it depends on how you define the container object. It may contain
completely the other object inside it, or it may just hold a
pointer/reference (that is: Other o, Other* o, Other& o are valid
alternatives). Unlike Python, the assignment `=` is an operator, and a=b
is an operation performed over the object `a` with argument `b` (because
`a` is a variable, pre-existent and pre-declared to be of a certain type).
In Object Pascal / Delphi, instance variables hold references to objects,
like Python (but basic types like integer, double, string aren't objects,
and you have to explicitely destroy objects when not needed anymore) [1].
a=b stores in `a`, a reference to the object `b`; you have no control over
its behavior.
In Smalltalk, things are like in Python I believe (my Smalltalk is
becoming more and more rusty). Objects hold references to other objects
(instance variables) - but encapsulation is strictly enforced, and they
can't be changed from the outside. Everything is resolved using message
passing between objects, except assignment: a:=b assigns the object `b` to
instance variable `a` directly.

[1] There was a way to declare objects which were not references (using
the 'object' keyword instead of 'class') but I'm not sure it is still
supported

--
Gabriel Genellina

--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-21 Thread r0g
Scott David Daniels wrote:
> I forgot to include a few cases:
> 
> (1) Inspired by your calling the class attributes "templates":


I did no such thing, I likened classes to templates and as far as I can
tell they are _like_ templates albeit dynamic ones.


> class Demo3(object):
> All the above to demonstrate the class storage and instance storage
> are separate.

I see that.

> (2) Trickier stuff involving sharing:
> class Demo4(object):

Yeah no s*** that's trickier! Still haven't quite wrapped my head round
it yet even after reading the 'language definitions carefully' (well
http://www.python.org/doc/2.5.2/tut/node11.html at least) although I am
a bit clearer about the difference between class attributes and instance
variables. Time to go rewrite some crappy old code!



> They are meant to point out that you need to read language definitions
> carefully, or you will breeze by thinking you understand something you
> really do not understand.

One of the things I love about Python is how it allows you to just
breeze by on intuition alone! It makes it immediately (and
incrementally) useful in the real world and I've been ableto built up a
great little library of scripts as I've learned. Having said that I
appreciate bigger projects require a deeper understanding which is why I
hang out here and occasionally ask dumb questions. Thankfully from time
to time clever bods like you will spot and point out the gaps in my
knowledge.

Cheers,

Roger.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-21 Thread Scott David Daniels

I forgot to include a few cases:

(1) Inspired by your calling the class attributes "templates":
class Demo3(object):
pass

d = Demo3()
print d.non_template  # raises exception
d.non_template = 45
print d.non_template
print Demo3.non_template  # raises exception
Demo3.non_template = 44
print d.non_template
print Demo3.non_template  # raises exception
del d.non_template
print d.non_template
del d.non_template  # raises exception
print d.non_template
del Demo3.non_template
print d.non_template  # raises exception

All the above to demonstrate the class storage and instance storage
are separate.

(2) Trickier stuff involving sharing:
class Demo4(object):
common = []

g = Demo4()
h = Demo4()
g.common.append('a')
print g.common, h.common, Demo4.common
g.common = g.common
Demo4.common = Demo4.common + ['b']
h.common = h.common
x = Demo4()
g.common.append('c')
h.common.append('d')
x.common.append('e')
print g.common, h.common, Demo4.common, x.common


Thanks for your reply and examples BTW (I think) they are helping me
clarify my understanding of python classes and the language used to
describe them.


They are meant to point out that you need to read language definitions
carefully, or you will breeze by thinking you understand something you
really do not understand.  Python provides a great way to experiment
with things you think you get; try "corner cases" to make sure you
know what is going on.

--Scott David Daniels
[EMAIL PROTECTED]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-21 Thread Joe Strout

On Nov 21, 2008, at 8:58 AM, r0g wrote:


I hadn't really appreciated the consequences of this till now though
e.g. that an instance might do a = a + 1 without affecting it's  
siblings
but that b.append("fish") would affect b for everyone. I don't know  
if I

will find any uses for that kind of behaviour but it doesn't hurt to
understand it :-)


Yes, it's critical to understanding any OOP language.


Isn't Python's behaviour a little peculiar in this respect though,
compared to classes in other languages?


No, it's exactly the same.


i.e. Are instances in other OO
languages like Smalltalk, C++ fully independent copies or do their
attribute names just point to one common object until reassigned  
like in

python? (Or have I still not it at all?!)


You're still a little confused, perhaps.  But I think this will clear  
it up:


  

I wrote this to help people in exactly your situation, so please do  
give me feedback and let me know how it did or didn't help.


Thanks,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-21 Thread r0g
Scott David Daniels wrote:
> r0g wrote:
>> ...
>> A class is like a template which combines a complex data type (made from
>> a combination of other data types) and the methods that operate on that
>> data type.
>>
>> You generally don't work with classes directly but you make instances of
>> them, each instance has it's own internal state and methods, initially
>> these are the same as the templates but can be changed or overridden
>> without affecting the state of any other instances you might have.
> Take the tutorial and do experiments.
> The attribute lookup checks the class _and_ the instance (with the
> instance over-riding the class).  Make sure you can explain the output
> from this:
> 
> class Demo(object):
> non_template = 43
> 
> d = Demo()
> print d.non_template
> Demo.non_template = 44
> print d.non_template
> d.non_template = 45
> print d.non_template
> Demo.non_template = 46
> print d.non_template
> 
> Once you can do that, explain this:
> class Demo2(object):
> holder = []
> 
> e = Demo2()
> print e.holder
> Demo2.holder.append(44)
> print e.holder
> e.holder.append(45)
> print e.holder
> Demo2.holder.append(46)
> print e.holder
> 
> # clue:
> print d.holder is Demo.holder
> 


Well that all makes sense what with Pythons' 'only copy explicity' and
lists being mutable and indeed, as you intuited, I did run into issues
with this within days of starting to learn Python! Ever since I have
been using copy.deepcopy() when I need to get the results described
above i.e. to ensure each instance is fully independent of all the others.

I hadn't really appreciated the consequences of this till now though
e.g. that an instance might do a = a + 1 without affecting it's siblings
but that b.append("fish") would affect b for everyone. I don't know if I
will find any uses for that kind of behaviour but it doesn't hurt to
understand it :-)

Isn't Python's behaviour a little peculiar in this respect though,
compared to classes in other languages? i.e. Are instances in other OO
languages like Smalltalk, C++ fully independent copies or do their
attribute names just point to one common object until reassigned like in
python? (Or have I still not it at all?!)


>> Is this correct enough for me to avoid the aforementioned bug pile?
>>
>> Also then, what _is_ an "instance variable" ?
> 
> Well, when you use the term variable, I suspect that you think it
> represents storage.  OK, it kind of does, but only in the sense

Well you used the term "instance variable" in your reply so I was just
asking if there _is_ an actual thing known as "an instance variable" in
Python and if so what it is/does.

Thanks for your reply and examples BTW (I think) they are helping me
clarify my understanding of python classes and the language used to
describe them.


Roger.

> --Scott David Daniels
> [EMAIL PROTECTED]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread Steven D'Aprano
On Thu, 20 Nov 2008 11:12:56 +1000, James Mills wrote:

> DON'T USE eval!

If you're going to make a sweeping generalization like that, at least 
offer some alternatives, and explain why eval should be avoided. 
Otherwise your advice is just cargo-cult programming.

eval is not inherently bad, it does have its uses. The timeit module, for 
instance, uses eval. But in general, there are better, faster ways of 
doing things than eval.

In my own testing, I find that eval('code') causes a serious speed hit: 
it's about ten times slower than just executing code directly.

eval also is a security risk, if you can't trust the code you are passing 
to it. You can *try* to mitigate those risks by filtering the string, and 
by setting the globals and locals arguments to eval, but you can't 
entirely remove the risk. The best way to remove the risk is to never use 
eval on untrusted code.



-- 
Steven
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread George Sakkis
On Nov 20, 6:54 pm, r0g <[EMAIL PROTECTED]> wrote:

> It would seem from this setattr function that the proper term for these
> is 'attributes'. That for many years I have considered pretty much any
> named thing that may vary a 'variable' might be at the root of the
> problem here as it's a very un-specific term...

Exactly, refrain from using the term "variable", or "value" for that
matter, in Python context as they are notorious for causing more
trouble than they deserve..

> So I gather you are saying that the fragments of state within a class
> are so distinct from ordinary common or garden variables that it is
> incorrect to think of them, or describe them, as variables, much like
> quarks should not really be regarded as distinct particles, and they
> should only be thought of and described as 'attributes' to avoid confusion?
>
> Is this correct enough for me to avoid the aforementioned bug pile?

No, a class can have attributes just like a instance can, and you can
use setattr() to set an attribute for a class just like you do it for
instances:

class Foo():
  bar = 1
  gum = 2

>>> setattr(Foo, 'bar', 3)
>>> Foo.bar
3

George
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread Scott David Daniels

r0g wrote:

...
A class is like a template which combines a complex data type (made from
a combination of other data types) and the methods that operate on that
data type.

You generally don't work with classes directly but you make instances of
them, each instance has it's own internal state and methods, initially
these are the same as the templates but can be changed or overridden
without affecting the state of any other instances you might have.

Take the tutorial and do experiments.
The attribute lookup checks the class _and_ the instance (with the
instance over-riding the class).  Make sure you can explain the output
from this:

class Demo(object):
non_template = 43

d = Demo()
print d.non_template
Demo.non_template = 44
print d.non_template
d.non_template = 45
print d.non_template
Demo.non_template = 46
print d.non_template

Once you can do that, explain this:
class Demo2(object):
holder = []

e = Demo2()
print e.holder
Demo2.holder.append(44)
print e.holder
e.holder.append(45)
print e.holder
Demo2.holder.append(46)
print e.holder

# clue:
print d.holder is Demo.holder


Is this correct enough for me to avoid the aforementioned bug pile?

Also then, what _is_ an "instance variable" ?


Well, when you use the term variable, I suspect that you think it
represents storage.  OK, it kind of does, but only in the sense
that it can hold a reference to an object.  A more successful
way of thinking is that the attribute name is associated with the
value.  In fact the object typically has a dictionary doing exactly
that, associating attribute names with values.  Both the class and
the instance have such dictionaries, although there are a few "specials"
that don't work that way (setattr knows about checking for the 
exceptional cases).  The "storage" can be removed with the "del"

statement.  Try
del d.non_template
print d.non_template
del e.holder
print e.holder

--Scott David Daniels
[EMAIL PROTECTED]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread Chris Rebert
On Thu, Nov 20, 2008 at 3:54 PM, r0g <[EMAIL PROTECTED]> wrote:
> Scott David Daniels wrote:
>> r0g wrote:
>>> John Machin wrote:
  You mention "variables of a class" but you then proceed to poke
 at an instance of the class
 Check out setattr (and getattr) in the docs.
>>> The former i.e. the variables of an instance of a class. Thanks :-)
>>
>> Careful here.  Your wording seems to indicate you misunderstand the
>> Python model.  The instance doesn't have variables (and your class built
>> nothing that could be called an instance variable).  Think of the
>> attributes of an instance (or a class) as "values attached to (or
>> associated with) the instance."  If you don't you are setting yourself
>> up to discover a pile of bugs that you don't understand.
>>
>> --Scott David Daniels
>> [EMAIL PROTECTED]
>
>
> OK now I'm confused, let me explain how I see things at the moment and
> you can correct me...
>
> A class is like a template which combines a complex data type (made from
> a combination of other data types) and the methods that operate on that
> data type.
>
> You generally don't work with classes directly but you make instances of
> them, each instance has it's own internal state and methods, initially
> these are the same as the templates but can be changed or overridden
> without affecting the state of any other instances you might have.
>
> While the perceived wisdom is that you should encapsulate all the
> methods you need to modify your classes' state within the class itself
> Python does (for better or worse) permit you to reach inside a class and
> futz with it's state directly from outside.
>
> The bits of an instance's state one might futz with (from within or
> without) i.e. the primitives that make up the complex object the class
> is a representation of, I think of as it's variables.
>
> It would seem from this setattr function that the proper term for these
> is 'attributes'. That for many years I have considered pretty much any
> named thing that may vary a 'variable' might be at the root of the
> problem here as it's a very un-specific term...
>
> So I gather you are saying that the fragments of state within a class
Within an instance
> are so distinct from ordinary common or garden variables that it is
> incorrect to think of them, or describe them, as variables, much like
> quarks should not really be regarded as distinct particles, and they
> should only be thought of and described as 'attributes' to avoid confusion?
>
> Is this correct enough for me to avoid the aforementioned bug pile?

Yes, I think so.

>
> Also then, what _is_ an "instance variable" ?

Metasyntatic variables:
  C - some class
  x - some instance
  y - the "word" after the dot in the expression: x.y


My working definitions based on my knowledge of Python:

Attribute - y is an attribute of x. Includes instance variables,
properties, and dynamically generated attributes. Since x.y really
ends up doing x.__getattribute__("y") behind the scenes, overriding
__getattribute__ lets you make attribute lookup more dynamic and have
it do interesting things. For example, you could write a class
overriding __getattribute__ so that x.y (for any valid Python name y)
opened a file with the name y and returned a file object for this file
(i.e. x.z returns file("z","w"), x.q returns file("q","w"), etc
without enumerating "q", "z", etc anywhere in the class).

Instance variable - In `x.y`, y is an instance variable of x if it's
stored in x.__dict__ or x.__slots__, it's not a method of x (though it
can be a function), and it's not a property.

Property - y is a property if x.y causes a method call and returns the
result of said method call. Basically, x.y becomes equivalent to x.z()
if y is a property. Properties can also allow `x.y = a` to be
equivalent to `x.z(a)` and `del x.y` to be equivalent to `x.z()`.
Properties are created using the built-in function property()

Class variable - Unless you're using metaclasses, in C.y, y is always
a class variable of C. Thus, methods are technically also class
variables. Using metaclasses, C is both a class itself and an instance
of another class D, in which case the definition of "instance
variable" (interpreted with regards to C being an instance of D)
applies to whether y is a class variable of C or not.

Class method - Created using the built-in function classmethod()

Essentially, attribute lookup is very dynamic in Python, which
complicates things a good bit, so the only thing we know for sure
about x.y is that y is an attribute of x.

Cheers,
Chris
-- 
Follow the path of the Iguana...
http://rebertia.com

>
> Thanks,
>
>
> Roger.
>
> Q: How many pedants does it take to change a lightbulb?
> A: Well actually you mean "replace" a lightbulb.
> Q: Have you ever kissed a girl?
> --
> http://mail.python.org/mailman/listinfo/python-list
>
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread r0g
Scott David Daniels wrote:
> r0g wrote:
>> John Machin wrote:
>>>  You mention "variables of a class" but you then proceed to poke
>>> at an instance of the class
>>> Check out setattr (and getattr) in the docs.
>> The former i.e. the variables of an instance of a class. Thanks :-)
> 
> Careful here.  Your wording seems to indicate you misunderstand the
> Python model.  The instance doesn't have variables (and your class built
> nothing that could be called an instance variable).  Think of the
> attributes of an instance (or a class) as "values attached to (or
> associated with) the instance."  If you don't you are setting yourself
> up to discover a pile of bugs that you don't understand.
> 
> --Scott David Daniels
> [EMAIL PROTECTED]


OK now I'm confused, let me explain how I see things at the moment and
you can correct me...

A class is like a template which combines a complex data type (made from
a combination of other data types) and the methods that operate on that
data type.

You generally don't work with classes directly but you make instances of
them, each instance has it's own internal state and methods, initially
these are the same as the templates but can be changed or overridden
without affecting the state of any other instances you might have.

While the perceived wisdom is that you should encapsulate all the
methods you need to modify your classes' state within the class itself
Python does (for better or worse) permit you to reach inside a class and
futz with it's state directly from outside.

The bits of an instance's state one might futz with (from within or
without) i.e. the primitives that make up the complex object the class
is a representation of, I think of as it's variables.

It would seem from this setattr function that the proper term for these
is 'attributes'. That for many years I have considered pretty much any
named thing that may vary a 'variable' might be at the root of the
problem here as it's a very un-specific term...

So I gather you are saying that the fragments of state within a class
are so distinct from ordinary common or garden variables that it is
incorrect to think of them, or describe them, as variables, much like
quarks should not really be regarded as distinct particles, and they
should only be thought of and described as 'attributes' to avoid confusion?

Is this correct enough for me to avoid the aforementioned bug pile?

Also then, what _is_ an "instance variable" ?

Thanks,


Roger.

Q: How many pedants does it take to change a lightbulb?
A: Well actually you mean "replace" a lightbulb.
Q: Have you ever kissed a girl?
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-20 Thread Scott David Daniels

r0g wrote:

John Machin wrote:

 You mention "variables of a class" but you then proceed to poke
at an instance of the class
Check out setattr (and getattr) in the docs.

The former i.e. the variables of an instance of a class. Thanks :-)


Careful here.  Your wording seems to indicate you misunderstand the
Python model.  The instance doesn't have variables (and your class built
nothing that could be called an instance variable).  Think of the
attributes of an instance (or a class) as "values attached to (or
associated with) the instance."  If you don't you are setting yourself
up to discover a pile of bugs that you don't understand.

--Scott David Daniels
[EMAIL PROTECTED]
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-19 Thread r0g
John Machin wrote:
> On Nov 20, 11:44 am, r0g <[EMAIL PROTECTED]> wrote:
>> Hi There,
>>
>> I know you can use eval to dynamically generate the name of a function
>> you may want to call. Can it (or some equivalent method) also be used to
>> do the same thing for the variables of a class e.g.
>>
>> class Foo():
>>   bar = 1
>>   gum = 2
>>
>> mylist = ['bar','gum']
>>
>> a = Foo()
>> for each in mylist:
>>   a.eval(each) = 999
>>
>> If so, what is the proper syntax/method for this.
> 
> You mention "variables of a class" but you then proceed to poke at an
> instance of the class. They are two different things. Which do you
> mean?
> 
> In any case, use the built-in function setattr to set attribute values
> for an object or for a class.
> 
> setattr(a, 'bar', 999) is equivalent to a.bar = 999
> setattr(Foo, 'bar', 456) is equivalent to Foo.bar = 456
> 
> Check out setattr (and getattr) in the docs.


The former i.e. the variables of an instance of a class. Thanks :-)

Roger.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-19 Thread r0g
George Sakkis wrote:
> On Nov 19, 7:44 pm, r0g <[EMAIL PROTECTED]> wrote:
>> Hi There,
>>
>> I know you can use eval to dynamically generate the name of a function
>> you may want to call. Can it (or some equivalent method) also be used to
>> do the same thing for the variables of a class e.g.
>>
>> class Foo():
>>   bar = 1
>>   gum = 2
>>
>> mylist = ['bar','gum']
>>
>> a = Foo()
>> for each in mylist:
>>   a.eval(each) = 999
>>
>> If so, what is the proper syntax/method for this.
> 
> for each in mylist:
> setattr(a, each, 999)
> 
> 
> HTH,
> George

Thank you George!

Damn I love Python! :0D
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-19 Thread John Machin
On Nov 20, 11:44 am, r0g <[EMAIL PROTECTED]> wrote:
> Hi There,
>
> I know you can use eval to dynamically generate the name of a function
> you may want to call. Can it (or some equivalent method) also be used to
> do the same thing for the variables of a class e.g.
>
> class Foo():
>   bar = 1
>   gum = 2
>
> mylist = ['bar','gum']
>
> a = Foo()
> for each in mylist:
>   a.eval(each) = 999
>
> If so, what is the proper syntax/method for this.

You mention "variables of a class" but you then proceed to poke at an
instance of the class. They are two different things. Which do you
mean?

In any case, use the built-in function setattr to set attribute values
for an object or for a class.

setattr(a, 'bar', 999) is equivalent to a.bar = 999
setattr(Foo, 'bar', 456) is equivalent to Foo.bar = 456

Check out setattr (and getattr) in the docs.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-19 Thread George Sakkis
On Nov 19, 7:44 pm, r0g <[EMAIL PROTECTED]> wrote:
> Hi There,
>
> I know you can use eval to dynamically generate the name of a function
> you may want to call. Can it (or some equivalent method) also be used to
> do the same thing for the variables of a class e.g.
>
> class Foo():
>   bar = 1
>   gum = 2
>
> mylist = ['bar','gum']
>
> a = Foo()
> for each in mylist:
>   a.eval(each) = 999
>
> If so, what is the proper syntax/method for this.

for each in mylist:
setattr(a, each, 999)


HTH,
George
--
http://mail.python.org/mailman/listinfo/python-list


Re: Using eval, or something like it...

2008-11-19 Thread James Mills
DON'T USE eval!

On Thu, Nov 20, 2008 at 10:44 AM, r0g <[EMAIL PROTECTED]> wrote:
> Hi There,
>
> I know you can use eval to dynamically generate the name of a function
> you may want to call. Can it (or some equivalent method) also be used to
> do the same thing for the variables of a class e.g.
>
> class Foo():
>  bar = 1
>  gum = 2
>
> mylist = ['bar','gum']
>
> a = Foo()
> for each in mylist:
>  a.eval(each) = 999
>
>
> If so, what is the proper syntax/method for this.
>
> Regards,
>
> Roger.
> --
> http://mail.python.org/mailman/listinfo/python-list
>



-- 
--
-- "Problems are solved by method"
--
http://mail.python.org/mailman/listinfo/python-list


Using eval, or something like it...

2008-11-19 Thread r0g
Hi There,

I know you can use eval to dynamically generate the name of a function
you may want to call. Can it (or some equivalent method) also be used to
do the same thing for the variables of a class e.g.

class Foo():
  bar = 1
  gum = 2

mylist = ['bar','gum']

a = Foo()
for each in mylist:
  a.eval(each) = 999


If so, what is the proper syntax/method for this.

Regards,

Roger.
--
http://mail.python.org/mailman/listinfo/python-list