Re: [Tutor] best way to dynamically set class variables?

2018-11-14 Thread Pablo Lucena
I really like the idea of using Python to generate another .py file with
the dynamic definitions taken into account.

That way you separate the "hackery" into a single function or module,
document how it works, and have it also annotate the dynamically generated
python source containing the class definitions as you need them with top of
file doc-string stating "this file was dynamically generated by xxx - don't
modify by hand".

That way your code is not confusing, you isolate the trick and the
resulting source, and you have full source files with all class attributes
that developers can look at and source control, rather than looking at a
weird looking class definition. It's just a simple python file after all,
no tricks.

On Fri, Nov 9, 2018 at 11:50 PM Albert-Jan Roskam 
wrote:

>
>
> On 10 Nov 2018 01:03, Steven D'Aprano  wrote:
>
> On Thu, Nov 08, 2018 at 11:34:35AM -0500, Avi Gross wrote:
> > An interesting discussion that is outside the scope of a group like this
> is
> > HOW malicious things can be done and perhaps how to avoid them.
> >
>
> Isn't the rule, simply:
>
> this_is_stupid = eval(input("please enter malicious code: "))
>
> ... and other uses range from 'code smell' to 'elegant' (where namedtuple
> is an example of the latter)
>
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
-- 
*Pablo Lucena*
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-09 Thread Albert-Jan Roskam



On 10 Nov 2018 01:03, Steven D'Aprano  wrote:

On Thu, Nov 08, 2018 at 11:34:35AM -0500, Avi Gross wrote:
> An interesting discussion that is outside the scope of a group like this is
> HOW malicious things can be done and perhaps how to avoid them.
>

Isn't the rule, simply:

this_is_stupid = eval(input("please enter malicious code: "))

... and other uses range from 'code smell' to 'elegant' (where namedtuple is an 
example of the latter)


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-09 Thread Steven D'Aprano
On Thu, Nov 08, 2018 at 11:34:35AM -0500, Avi Gross wrote:
> An interesting discussion that is outside the scope of a group like this is
> HOW malicious things can be done and perhaps how to avoid them.
> 
> Obviously some contexts are totally uncontrolled. If you write a
> "calculator" that asks the user to type in an arbitrary string like
> "2*(3+5)" or "sin(30)" and execute that string and show the result, then
> they can slip in anything like a shell command to reformat the hard disk.

If they want to reformat their own hard disk, there are much easier ways 
than slipping a shell command into a Python calculator.

The risk, tiny as it is, is that something which starts life as a 
desktop application running on the user's own computer gets extracted 
out into a library used in a web application running on somebody else's 
server. So in that sense, it is better to avoid eval/exec even on 
locally-run desktop applications.

But it is *critical* to avoid eval or exec on untrusted input running on 
a server.


> What can you do to minimize risks in such situations?

(1) Don't use eval or exec.

(2) If you must use eval or exec, consider allowing only a whitelist of 
allowed commands. You can do that by specifying the global and local 
namespace arguments:

ns = {'round': round, 'sin': math.sin, '__builtins__': None}
eval(command, ns, ns)

You must set __builtins__ to something, if it is missing, the 
interpreter will set it to the real builtins module and open the doors 
wide open.

(3) Don't use eval or exec.

(4) But even with a whitelist, it is remarkably easy to break out of the 
sandbox. Most(?) tricks for doing so involve using dunder (Double 
UNDERscore) attributes, so a quick palliative for this is to disallow 
any command that includes an underscore:

if '_' in command:
 raise InvalidCommand('syntax error: no underscores allowed')
else:
 eval(command, ns, ns)

(5) Its okay to use eval and exec for your own use, at the interactive 
interpreter, or in quick scripts you use in a trusted environment.

(6) But even if you successfully block all the escape tricks, the user 
can trivially DOS (Denial Of Service) your calculator web app:

command = '(2**1000)**(2**1000)**(2**1000)'

so you need to run it in an environment where evaluation will timeout 
after a certain amount of time, without using up all the memory on your 
server.

(7) For experts, its okay to use eval or exec. Maybe.


For a good use of exec, see the source code to namedtuple in the 
collections module. Or this:

http://code.activestate.com/recipes/578918-yet-another-namedtuple/


-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-09 Thread Albert-Jan Roskam
On 8 Nov 2018 17:34, Avi Gross  wrote:

> What can you do to minimize risks in such > situations?

ast.literal_eval, with a smallish maximum string length? 
https://docs.python.org/3/library/ast.html.

(That's exactly the only ast function that know! :-)
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-09 Thread Avi Gross
An interesting discussion that is outside the scope of a group like this is
HOW malicious things can be done and perhaps how to avoid them.

Obviously some contexts are totally uncontrolled. If you write a
"calculator" that asks the user to type in an arbitrary string like
"2*(3+5)" or "sin(30)" and execute that string and show the result, then
they can slip in anything like a shell command to reformat the hard disk.

What can you do to minimize risks in such situations? Obviously you might
want to scan the string before executing and look for things like carriage
returns and semi-colons that might be used to add continuation commands
beyond what is asked for. You might limit the length of the string. You
might scan for keywords like def and lambda. But note that a cursory scan
like that has false positives as well as false negatives. You might
recognize something within a character string context that is harmless or
you might reject a valid SQL query because it used a word you disallow that
is actually a harmless name of a data column.

And, realistically, Python has so many ways to get around things that it
gets silly. Given some room and ingenuity, you can create code that
assembles individual characters and then executes them into a program so a
scan may not reveal anything.

Heck, if you can simply create a module on the disk somewhere, all you need
to do is insert enough code to IMPORT the file and you can do pretty much
anything. If asked to enter a calculator entry, for example, and you simply
say:

5+3;import mymodule

You then have an exec("5+3;import mymodule")

Some such things may generate an error but only after the side effect is
done.

Python code is often wide open, by design, so subtle messing with internals
is easy. As an example, you can change the search path for modules with an
assignment statement and then any subsequent call for importing a named
module gets the one you substituted.

So, yes, executing random code can be dangerous. But life is dangerous

-Original Message-
From: Tutor  On Behalf Of
Alan Gauld via Tutor
Sent: Thursday, November 8, 2018 5:52 AM
To: tutor@python.org
Subject: Re: [Tutor] best way to dynamically set class variables?

On 08/11/2018 07:46, Peter Otten wrote:

> By the way I don't think exec() is bad as long as you control its 
> input and as long as this input is fairly simple.

Yes, but reading arbitrary column names from a database is not exactly
controlled input...


--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-08 Thread srinivasan
Once again thanks a lot guys for all your help and I really appreciate it
that I can really come back to you, if am stuck with any python issues, as
i was really a embedded linux platform developer

>From now I have learnt not to use much bash commands with pipe and to just
use the bash command and parse it using python code

For now I have simplified and it working as below, might be useful for
others sometime


def get_fstype_of_mounted_partition(self, partition_path):
"""
Get the filesystem type of the mounted partition.

:partition_name : Partition path as string (e.g. /dev/mmcblk0p1)
:return: filesystem type as string
"""

cmd = "lsblk %s -n -o FSTYPE" % partition_path
return self._helper.execute_cmd_output_string(cmd)

On Thu, Nov 8, 2018 at 11:11 AM Avi Gross  wrote:

> I have been reading the replies and wonder sometimes if we understand the
> real question as intended.
>
> Classes in Python can be changed in all kinds of ways even after they have
> been defined and the changes take effect on any new instances created
> afterward. So can instances in multiple ways. If you want to store the
> names
> of a hundred columns in a variable or even a hundred variables, you have
> ways to assign them. You can even change methods on the fly.
>
> If what you want is even more flexibility to design the class later after
> receiving more data such as the names and types of the columns in a data
> table, you can either write the description as text into a temporary file
> and import it, if that makes sense, or make a string to be evaluated in
> memory. Both can be dangerous if you do not trust the parts added as the
> code is going to be run at runtime and can do malicious things.
>
> Python often has so many ways to do things that various ones may work
> better
> for you. In your case, one example would be to intercept the ability to set
> and get (unknown) components of a class or instance by using the right
> dunder function such as __getattr__ and have it KNOW about your dynamic
> variable names and control access to them. There are many ways to do this,
> CAREFULLY, and some work only or differently in new style classes. Heck,
> you
> can put all the important code in an external function called by the above
> that can dynamically be made in Python at a later time. One architecture
> might be to store your new info in one or more dictionaries and have that
> functionality check if a valid request is made and return it. Obviously it
> matters where you want the data held as in per instance or per class or
> superclass and so on.
>
> Of course, I may misunderstand your issue. But from what it sounds like,
> your main request is a way to associate multiple items to be stored after a
> class is created but before it is used. There are an amazing number of ways
> even before you loom at more advanced methods like decorators.
>
> -----Original Message-
> From: Tutor  On Behalf Of
> Oscar Benjamin
> Sent: Wednesday, November 7, 2018 5:33 PM
> To: tutor@python.org
> Subject: Re: [Tutor] best way to dynamically set class variables?
>
> On Wed, 7 Nov 2018 at 18:35, Alan Gauld via Tutor 
> wrote:
> >
> > On 07/11/2018 14:48, Albert-Jan Roskam wrote:
> >
> > > What is the best way to dynamically set class variables?
> >
> > I think I'm maybe missing the point of your question?
>
> I think you are as well :)
>
> IIUC then the question is: how can I programatically/dynamically create a
> class that has some attributes derived from data that is known at runtime?
>
> Am I understanding this correctly Albert?
>
> > > # ---
> > > class Parent: pass
> > > class_vars = dict(col1='str', col2='int')
> > >
> > > # approach 1
> > > Child = type('Child', (Parent,), class_vars)
>
> This seems fine to me. It may seem cryptic but that's only because it's
> unusual to do this. You are creating a "type" and that is the constructor
> for type objects.
>
> --
> Oscar
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
> ___
> Tutor maillist  -  Tutor@python.org
> To unsubscribe or change subscription options:
> https://mail.python.org/mailman/listinfo/tutor
>
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-08 Thread Alan Gauld via Tutor
On 08/11/2018 07:46, Peter Otten wrote:

> By the way I don't think exec() is bad as long as you control its input and 
> as long as this input is fairly simple.

Yes, but reading arbitrary column names from a database
is not exactly controlled input...


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-08 Thread Avi Gross
I have been reading the replies and wonder sometimes if we understand the
real question as intended.

Classes in Python can be changed in all kinds of ways even after they have
been defined and the changes take effect on any new instances created
afterward. So can instances in multiple ways. If you want to store the names
of a hundred columns in a variable or even a hundred variables, you have
ways to assign them. You can even change methods on the fly.

If what you want is even more flexibility to design the class later after
receiving more data such as the names and types of the columns in a data
table, you can either write the description as text into a temporary file
and import it, if that makes sense, or make a string to be evaluated in
memory. Both can be dangerous if you do not trust the parts added as the
code is going to be run at runtime and can do malicious things.

Python often has so many ways to do things that various ones may work better
for you. In your case, one example would be to intercept the ability to set
and get (unknown) components of a class or instance by using the right
dunder function such as __getattr__ and have it KNOW about your dynamic
variable names and control access to them. There are many ways to do this,
CAREFULLY, and some work only or differently in new style classes. Heck, you
can put all the important code in an external function called by the above
that can dynamically be made in Python at a later time. One architecture
might be to store your new info in one or more dictionaries and have that
functionality check if a valid request is made and return it. Obviously it
matters where you want the data held as in per instance or per class or
superclass and so on.

Of course, I may misunderstand your issue. But from what it sounds like,
your main request is a way to associate multiple items to be stored after a
class is created but before it is used. There are an amazing number of ways
even before you loom at more advanced methods like decorators.

-Original Message-
From: Tutor  On Behalf Of
Oscar Benjamin
Sent: Wednesday, November 7, 2018 5:33 PM
To: tutor@python.org
Subject: Re: [Tutor] best way to dynamically set class variables?

On Wed, 7 Nov 2018 at 18:35, Alan Gauld via Tutor  wrote:
>
> On 07/11/2018 14:48, Albert-Jan Roskam wrote:
>
> > What is the best way to dynamically set class variables?
>
> I think I'm maybe missing the point of your question?

I think you are as well :)

IIUC then the question is: how can I programatically/dynamically create a
class that has some attributes derived from data that is known at runtime?

Am I understanding this correctly Albert?

> > # ---
> > class Parent: pass
> > class_vars = dict(col1='str', col2='int')
> >
> > # approach 1
> > Child = type('Child', (Parent,), class_vars)

This seems fine to me. It may seem cryptic but that's only because it's
unusual to do this. You are creating a "type" and that is the constructor
for type objects.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Peter Otten
Alan Gauld via Tutor wrote:

>>exec() might even be a way
> 
> It's a way but it's a bad way! :-)

And then

> A simple approach you could use would be to get Python to
> generate a new python file(module) containing the required class
> definition (simple string processing) and then dynamically
> import the new file.

That's basically exec(), with better tracebacks and a higher chance to run 
outdated code ;)

By the way I don't think exec() is bad as long as you control its input and 
as long as this input is fairly simple.


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Alan Gauld via Tutor
On 07/11/2018 23:06, Alan Gauld via Tutor wrote:

>> Imagine having to write this for 100 columns, brrr.
> 
> No problem, I've done that dozens of time for production C++ code,
> it's business as usual in commercial programming.
> 
> Of course I'd get the data from a meta SQL query and feed it into an
> emacs macro to generate the code but I'd still have to churn out the
> class definitions. (Or I might even write a Python program to generate
> the C++ code for me) But it's eminently doable and keeps the rest of the
> code simple.
It just occurred to me that this bit of C++ nostalgia might
not be as irrelevant as I first thought.

A simple approach you could use would be to get Python to
generate a new python file(module) containing the required class
definition (simple string processing) and then dynamically
import the new file.

Very similar to my emacs macro approach except with dynamic
loading.

You'd probably need a batch/cron job to version control
all these new files too...

And I've no idea how efficient that would be if there were
a lot of tables to be processed - but in that scenario I suspect
the whole class per table approach is flawed!

Just a thought... or 3...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Alan Gauld via Tutor
On 07/11/2018 23:06, Alan Gauld via Tutor wrote:

> Another option would be to explore metaclasses
> and modify the class creation mechanism

Which, of course, is what you were doing with the type(...)
call in your post...

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Alan Gauld via Tutor
On 07/11/2018 20:07, Albert-Jan Roskam wrote:

> I should have mentioned that the code ... should be able to convert 
> an *arbitrary* Sql server table into hdf5 format*). 

Umm, yes that would have helped!

 from tables import *
 class Particle(IsDescription):
> ... name  = StringCol(16)   # 16-character String
> ... idnumber  = Int64Col()  # Signed 64-bit integer
> ... ADCcount  = UInt16Col() # Unsigned short integer
> ... TDCcount  = UInt8Col()  # unsigned byte
> ... grid_i= Int32Col()  # 32-bit integer
> ... grid_j= Int32Col()  # 32-bit integer
> ... pressure  = Float32Col()# float  (single-precision)
> ... energy= Float64Col()# double (double-precision)
> 
> 
> Imagine having to write this for 100 columns, brrr.

No problem, I've done that dozens of time for production C++ code,
it's business as usual in commercial programming.

Of course I'd get the data from a meta SQL query and feed it into an
emacs macro to generate the code but I'd still have to churn out the
class definitions. (Or I might even write a Python program to generate
the C++ code for me) But it's eminently doable and keeps the rest of the
code simple.

Of course Python allows for dynamic creation of classes so you
can be more subtle than that. :-)

> So the code grabs the sql column names and the datatypes 
> and translates that into the hdf5 equivalent. 

Should be relatively easy to write a function to do that.
I'm not clear if the class definition already exists
or if you are trying to create the class (Based on
the table name maybe?)as well as its attributes?

Also column names are usually instance attributes not
class attributes. Each instance of the class being a
row in the table...


> And pytables uses a class, with class variables, to define this.

No idea what pytables is or what it does so can't comment.

> A classmethod might be nice. I've never used this before, 

If there is some kind of abstract superclass (TableModel
or somesuch?) then a class method there could spin off the
new subclasses.

>  exec() might even be a way

It's a way but it's a bad way! :-)

Another option would be to explore metaclasses
and modify the class creation mechanism


-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Oscar Benjamin
On Wed, 7 Nov 2018 at 18:35, Alan Gauld via Tutor  wrote:
>
> On 07/11/2018 14:48, Albert-Jan Roskam wrote:
>
> > What is the best way to dynamically set class variables?
>
> I think I'm maybe missing the point of your question?

I think you are as well :)

IIUC then the question is: how can I programatically/dynamically
create a class that has some attributes derived from data that is
known at runtime?

Am I understanding this correctly Albert?

> > # ---
> > class Parent: pass
> > class_vars = dict(col1='str', col2='int')
> >
> > # approach 1
> > Child = type('Child', (Parent,), class_vars)

This seems fine to me. It may seem cryptic but that's only because
it's unusual to do this. You are creating a "type" and that is the
constructor for type objects.

--
Oscar
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Steven D'Aprano
On Wed, Nov 07, 2018 at 02:48:40PM +, Albert-Jan Roskam wrote:

> What is the best way to dynamically set class variables? I am looking 
> for a generalization of something like this:
> 
> class Parent: pass
> class Child(Parent):
> col1 = 'str'
> col2 = 'int'

The obvious solution is to do exactly that: just set the class attribute
in the subclass. If the value is dynamically generated, so be it:

class Child(Parent):
col1 = calculate_some_value()
col2 = col1 + calculate_something_else()


If the names of the class attributes themselves have to be generated, 
that's what locals() is for:


class Child(Parent):
for i in range(10):
name = "column" + str(i)
locals()[name] = i
del i

will give you class attributes column0 = 0, column1 = 1, etc. Of course 
you can generate the names any way you like, e.g. read them from a text 
file.

A cleaner solution might be to move the code into a function and pass 
the class namespace to it:


def make_attrs(ns):
for i in range(10):
name = "column" + str(i)
ns[name] = i

class Child(Parent):
make_attrs(locals())
assert column0 == 0

assert Child.column1 == 1



Does this help?



-- 
Steve
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Albert-Jan Roskam



On 7 Nov 2018 20:36, Mats Wichmann  wrote:
Not sure what you're after, but what's wrong with just setting them?

Parent.avar = "a class var"

Hi Alan, Mats,

I should have mentioned that the code is part of a function sql_to_hdf5. So it 
should be able to convert an *arbitrary* Sql server table into hdf5 format*). 
But even if it was just one specific table: it's quite cumbersome to write the 
column names (class variable names) and the target hdf5 data types (class 
variable values) for, say, a hundred columns. This is an example from the 
pytables website:


>>> from tables import *
>>> class Particle(IsDescription):
... name  = StringCol(16)   # 16-character String
... idnumber  = Int64Col()  # Signed 64-bit integer
... ADCcount  = UInt16Col() # Unsigned short integer
... TDCcount  = UInt8Col()  # unsigned byte
... grid_i= Int32Col()  # 32-bit integer
... grid_j= Int32Col()  # 32-bit integer
... pressure  = Float32Col()# float  (single-precision)
... energy= Float64Col()# double (double-precision)


Imagine having to write this for 100 columns, brrr.

So the code grabs the sql column names and the datatypes (easy with sqlalchemy) 
and translates that into the hdf5 equivalent. And pytables uses a class, with 
class variables, to define this.

A classmethod might be nice. I've never used this before, but I'll try this (I 
did try __new__ this afternoon, but it looked even more complicated). And it 
just occurred to me that exec() might even be a way (namedtuple does it, too). 
Or should I now grab my coat for even mentioning exec? :-)))

Best wishes,
Albert-Jan

*) I tried using pandas to_hdf for this, but this does not work wel with mixed 
dtypes, NULL values, and chunkwise reading.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Mats Wichmann
Not sure what you're  after, but what's wrong with just setting them?

Parent.avar = "a class var"

On November 7, 2018 7:48:40 AM MST, Albert-Jan Roskam  
wrote:
>Hi,
>
>Background: In my code I use sqlalchemy to read SQL server data. I want
>to write that data to HDF5 using pytables (see 'declaring a column
>descriptor': https://www.pytables.org/usersguide/tutorials.html). My
>question is not about pytables or sqlalchemy per se, but I thought it
>would be informative to mention this. 
>
>What is the best way to dynamically set class variables? I am looking
>for a generalization of something like this:
>
>class Parent: pass
>class Child(Parent):
>col1 = 'str'
>col2 = 'int'
>
>Several (im)possible solutions:
>
># ---
>class Parent: pass
>class_vars = dict(col1='str', col2='int')
>
># approach 1
>Child = type('Child', (Parent,), class_vars)
>
># approach 2
>class Child(Parent): pass
>Child.__dict__.update( class_vars )  # AttributeError: 'mappingproxy'
>object has no attribute 'update'
>
># approach 3
>class Child(Parent): pass
>for k, v in class_vars.items():
>setattr(Child, k, v)
>
>I initially chose approach #1, but I find this way of defining a class
>quite cryptic (but then, it's part of the language definition!). What's
>the best way to do this? I am using Python 3.5 (Windows). Thanks in
>advance!
>
>Best wishes,
>Albert-Jan
>___
>Tutor maillist  -  Tutor@python.org
>To unsubscribe or change subscription options:
>https://mail.python.org/mailman/listinfo/tutor

-- 
Sent from my Android device with K-9 Mail. Please excuse my brevity.
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] best way to dynamically set class variables?

2018-11-07 Thread Alan Gauld via Tutor
On 07/11/2018 14:48, Albert-Jan Roskam wrote:

> What is the best way to dynamically set class variables? 

Remember the golden rule of OOP is that objects(and classes)
should do it to themselves. Ideally the class variables
should be there to support some kind of class behaviour
and that behaviour should set the variables. (Reading is
arguably different, it's usually OK for external objects
to "grab a value" from a class. But if you are modifying
it from outside then who is doing what and should that
"what" not be done by the class (maybe in a class method)?

Having said that, if you can find a valid scenario where
objects/functions outside the class need to modify the
internals of the class directly then directly is how
they should do it.

class C:
   classvar = 'foo'

x = C.classvar  # read directly
C.classvar = 'bar'  # assign directly

I am looking for a generalization of something like this:
> 
> class Parent: pass
> class Child(Parent):
> col1 = 'str'
> col2 = 'int'

What's not general about that?
I think I'm maybe missing the point of your question?

> # ---
> class Parent: pass
> class_vars = dict(col1='str', col2='int')
> 
> # approach 1
> Child = type('Child', (Parent,), class_vars)
> 
> # approach 2
> class Child(Parent): pass
> Child.__dict__.update( class_vars )  # AttributeError: 'mappingproxy' object 
> has no attribute 'update'
> 
> # approach 3
> class Child(Parent): pass
> for k, v in class_vars.items():
> setattr(Child, k, v)

That all seems incredibly complicated and I'm not
sure what it would buy you over direct assignment?

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor


[Tutor] best way to dynamically set class variables?

2018-11-07 Thread Albert-Jan Roskam
Hi,

Background: In my code I use sqlalchemy to read SQL server data. I want to 
write that data to HDF5 using pytables (see 'declaring a column descriptor': 
https://www.pytables.org/usersguide/tutorials.html). My question is not about 
pytables or sqlalchemy per se, but I thought it would be informative to mention 
this. 

What is the best way to dynamically set class variables? I am looking for a 
generalization of something like this:

class Parent: pass
class Child(Parent):
col1 = 'str'
col2 = 'int'

Several (im)possible solutions:

# ---
class Parent: pass
class_vars = dict(col1='str', col2='int')

# approach 1
Child = type('Child', (Parent,), class_vars)

# approach 2
class Child(Parent): pass
Child.__dict__.update( class_vars )  # AttributeError: 'mappingproxy' object 
has no attribute 'update'

# approach 3
class Child(Parent): pass
for k, v in class_vars.items():
setattr(Child, k, v)

I initially chose approach #1, but I find this way of defining a class quite 
cryptic (but then, it's part of the language definition!). What's the best way 
to do this? I am using Python 3.5 (Windows). Thanks in advance!

Best wishes,
Albert-Jan
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor