Re: [Tutor] best way to dynamically set class variables?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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?
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