creating class instances from a list - python

Using python.....I have a list that contain names. I want to use each item in the list to create instances of a class. I can't use these items in their current condition (they're strings). Does anyone know how to do this in a loop.
class trap(movevariables):
def __init__(self):
movevariables.__init__(self)
if self.X==0:
self.X=input('Move Distance(mm) ')
if self.Vmax==0:
self.Vmax=input('Max Velocity? (mm/s) ')
if self.A==0:
percentg=input('Acceleration as decimal percent of g' )
self.A=percentg*9806.65
self.Xmin=((self.Vmax**2)/(2*self.A))
self.calc()
def calc(self):
if (self.X/2)>self.Xmin:
self.ta=2*((self.Vmax)/self.A) # to reach maximum velocity, the move is a symetrical trapezoid and the (acceleration time*2) is used
self.halfta=self.ta/2. # to calculate the total amount of time consumed by acceleration and deceleration
self.xa=.5*self.A*(self.halfta)**2
else: # If the move is not a trap, MaxV is not reached and the acceleration time is set to zero for subsequent calculations
self.ta=0
if (self.X/2)<self.Xmin:
self.tva=(self.X/self.A)**.5
self.halftva=self.tva/2
self.Vtriang=self.A*self.halftva
else:
self.tva=0
if (self.X/2)>self.Xmin:
self.tvc=(self.X-2*self.Xmin)/(self.Vmax) # calculate the Constant velocity time if you DO get to it
else:
self.tvc=0
self.t=(self.ta+self.tva+self.tvc)
print self
I'm a mechanical engineer. The trap class describes a motion profile that is common throughout the design of our machinery. There are many independent axes (trap classes) in our equipment so I need to distinguish between them by creating unique instances. The trap class inherits from movevariables many getter/setter functions structured as properties. In this way I can edit the variables by using the instance names. I'm thinking that I can initialize many machine axes at once by looping through the list instead of typing each one.

You could use a dict, like:
classes = {"foo" : foo, "bar" : bar}
then you could do:
myvar = classes[somestring]()
this way you'll have to initialize and keep the dict, but will have control on which classes can be created.

The getattr approach seems right, a bit more detail:
def forname(modname, classname):
''' Returns a class of "classname" from module "modname". '''
module = __import__(modname)
classobj = getattr(module, classname)
return classobj
From a blog post by Ben Snider.

If it a list of classes in a string form you can:
classes = ['foo', 'bar']
for class in classes:
obj = eval(class)
and to create an instance you simply do this:
instance = obj(arg1, arg2, arg3)

EDIT
If you want to create several instances of the class trap, here is what to do:
namelist=['lane1', 'lane2']
traps = dict((name, trap()) for name in namelist)
That will create a dictionary that maps each name to the instance.
Then to access each instance by name you do:
traps['lane1'].Vmax

you're probably looking for getattr.

Related

How to call a function within an attribute? [duplicate]

This question already has answers here:
How to access (get or set) object attribute given string corresponding to name of that attribute
(3 answers)
Closed 3 years ago.
I have a Python class that have attributes named: date1, date2, date3, etc.
During runtime, I have a variable i, which is an integer.
What I want to do is to access the appropriate date attribute in run time based on the value of i.
For example,
if i == 1, I want to access myobject.date1
if i == 2, I want to access myobject.date2
And I want to do something similar for class instead of attribute.
For example, I have a bunch of classes: MyClass1, MyClass2, MyClass3, etc. And I have a variable k.
if k == 1, I want to instantiate a new instance of MyClass1
if k == 2, I want to instantiate a new instance of MyClass2
How can i do that?
EDIT
I'm hoping to avoid using a giant if-then-else statement to select the appropriate attribute/class.
Is there a way in Python to compose the class name on the fly using the value of a variable?
You can use getattr() to access a property when you don't know its name until runtime:
obj = myobject()
i = 7
date7 = getattr(obj, 'date%d' % i) # same as obj.date7
If you keep your numbered classes in a module called foo, you can use getattr() again to access them by number.
foo.py:
class Class1: pass
class Class2: pass
[ etc ]
bar.py:
import foo
i = 3
someClass = getattr(foo, "Class%d" % i) # Same as someClass = foo.Class3
obj = someClass() # someClass is a pointer to foo.Class3
# short version:
obj = getattr(foo, "Class%d" % i)()
Having said all that, you really should avoid this sort of thing because you will never be able to find out where these numbered properties and classes are being used except by reading through your entire codebase. You are better off putting everything in a dictionary.
For the first case, you should be able to do:
getattr(myobject, 'date%s' % i)
For the second case, you can do:
myobject = locals()['MyClass%s' % k]()
However, the fact that you need to do this in the first place can be a sign that you're approaching the problem in a very non-Pythonic way.
OK, well... It seems like this needs a bit of work. Firstly, for your date* things, they should be perhaps stored as a dict of attributes. eg, myobj.dates[1], so on.
For the classes, it sounds like you want polymorphism. All of your MyClass* classes should have a common ancestor. The ancestor's __new__ method should figure out which of its children to instantiate.
One way for the parent to know what to make is to keep a dict of the children. There are ways that the parent class doesn't need to enumerate its children by searching for all of its subclasses but it's a bit more complex to implement. See here for more info on how you might take that approach. Read the comments especially, they expand on it.
class Parent(object):
_children = {
1: MyClass1,
2: MyClass2,
}
def __new__(k):
return object.__new__(Parent._children[k])
class MyClass1(Parent):
def __init__(self):
self.foo = 1
class MyClass2(Parent):
def __init__(self):
self.foo = 2
bar = Parent(1)
print bar.foo # 1
baz = Parent(2)
print bar.foo # 2
Thirdly, you really should rethink your variable naming. Don't use numbers to enumerate your variables, instead give them meaningful names. i and k are bad to use as they are by convention reserved for loop indexes.
A sample of your existing code would be very helpful in improving it.
to get a list of all the attributes, try:
dir(<class instance>)
I agree with Daenyth, but if you're feeling sassy you can use the dict method that comes with all classes:
>>> class nullclass(object):
def nullmethod():
pass
>>> nullclass.__dict__.keys()
['__dict__', '__module__', '__weakref__', 'nullmethod', '__doc__']
>>> nullclass.__dict__["nullmethod"]
<function nullmethod at 0x013366A8>

Quick way to convert all instance variables in a class, to a list (Python)

I have created a class with around 100+ instance variables (as it will be used in a function to do something else).
Is there a way to translate all the instance variables; into an array list. Without manually appending each instance variable.
For instance:
class CreateHouse(object):
self.name = "Foobar"
self.title = "FooBarTest"
self.value = "FooBarValue"
# ...
# ...
# (100 more instance variables)
Is there a quicker way to append all these items to a list:
Quicker than:
theList = []
theList.append(self.name)
theList.append(self.title)
theList.append(self.value)
# ... (x100 elements)
The list would be used to perform another task, in another class/method.
The only solution (without totally rethinking your whole design - which FWIW might be an option to consider, cf my comments on your question) is to have a list of the attribute names (in the order you want them in the final list) and use getattr
class MonstruousGodClass(object):
_fields_list = ["name", "title", "value", ] #etc...
def as_list(self):
return [getattr(self, fieldname) for fieldname in self._fields_list]
Now since, as I mentionned in a comment, a list is NOT the right datatype here (from a semantical POV at least), you may want to use a dict instead - which makes the code much simpler:
import copy
def as_dict(self):
# we return a deepcopy to avoid unexpected side-effects
return copy.deepcopy(self.__dict__)

Python: Iterating over a group of symbols

I'm frequently finding myself in a situation where I have a group of logically connected symbols that I want to iterate over. The obvious solution is to add these symbols to a list, but the duplication is a pain to maintain and I have to trust that if my fellow devs change one they also change the other.
Is there a way to create symbols while simultaneously adding their value to, say, a list?
For example
# A group of like symbols that can be used independently in this scope
hippo = 'hippo'
gator = 'gator'
mouse = 'mouse'
# To loop across them I have to put them into a list
valid_animals = [hippo, gator, mouse] # Maintain me separately, fool!
Psuedo-code for what I want
# Data structure that declares symbols whose values can be iterated over
valid_animals = { # Even your mom could maintain this
hippo = 'hippo'
gator = 'gator'
mouse = 'mouse'
}
# Use the symbols by themselves
print "I had a", mouse, "in my house"
# Iterate over the symbols
print mouse in valid_animals # True
This sounds like what object-oriented programming is for:
class Animal(object):
list = []
def __init__(self,name):
self.name = name
Animal.list.append(self.name)
mouse = Animal("mouse")
cat = Animal("cat")
print(mouse) # <test.Animal object at 0x7f835e146860>
print(mouse.name) # 'mouse'
print(cat.name) # 'cat'
print(Animal.list) # ['mouse', 'cat']
Typically, in Python, classes have an init method. This can seem mysterious, but all it really is is some code that is called when an object is instantiated based on the class. (Think of the class as a template for creating objects, and the init method runs when the object is created.)
Inside the class, make an empty list. This is a class-level list and can be accessed in your code with Animal.list. It's not connected with any particular instantiated object (i.e., cat or mouse).
When the init method is called, the name of the newly-created object is added to the class-level list. So if you create ten animals (Animal('ocelot'), Animal('kangaroo'), etc), you can call Animal.list to see the names of all the animals.
EDIT: You requested a more general solution to your problem:
class Symbol(object):
types = []
def __init__(self,name):
self.name = name
Symbol.types.append(self.name)
self.item_list = []
def add(self,item):
self.item_list.append(item)
animal = Symbol('animal')
print(animal.item_list) # []
animal.add('tiger')
animal.add('llama')
print(animal.item_list) # ['tiger', 'llama']
food = Symbol('food')
food.add('carrot')
food.add('beans')
print(food.item_list) # ['carrot', 'beans']
print(Symbol.types) # ['animal', 'food']
A idea it to just maintain the the list : valid=['foo','bar','baz'].
If at a moment you want for convenience to define variable with the same name,locals().update(zip(valid,valid)) will do it.
But it's surely a bad idea in serious projects.
I'm not sure if this is a good idea for any large project, but you could do the following:
def varsFromStrings(*strings):
newVars = []
for s in strings:
globals()[s] = s
newVars.append(s)
return newVars
The function will take a list of strings, create variables for each string, enter these variables into the globals dictionary, and assign the string to each variables, returning the list of strings as a result. Then even your Mom could type:
valid_animals = varsFromStrings('hippo','gator','mouse')
after which,
print("I had a", mouse, "in my house")
for critter in valid_animals: print(critter)
both work as expected.
This might be helpful in some smallish programs, but if program maintenance is a concern -- why not just use a regular dictionary of valid animals?
#T. Arboreus was right; the solution was object oriented programing. In order to declare symbols in the local scope while simultaneously adding them to an iterable, all I needed was a return value on an append action which could then be assigned to my symbol.
I did this by inheriting from list and adding a bind method.
# Iterable object that has a return on append
class SymGroup(list):
def add(self, value):
self.append(value)
return value
# Create my list that represents a group of symbol values
valid_animals = SymGroup()
# Assign and append values at the same time
hippo = valid_animals.bind("hippo")
gator = valid_animals.bind("gator")
mouse = valid_animals.bind("mouse")
# Symbol can be used by itself
print "There is a", mouse, "in my house"
# Can iterate across the symbol values
print mouse in valid_animals # True
print "horse" in valid_animals # False
Now I only have to maintain the one declaration.

Calling classmethods through a dictionary

I'm working on a class describing an object that can be expressed in several "units", I'll say, to keep things simple. Let's say we're talking about length. (It's actually something more complicated.) What I would like is for the user to be able to input 1 and "inch", for example, and automatically get member variables in feet, meters, furlongs, what have you as well. I want the user to be able to input any of the units I am dealing in, and get member variables in all the other units. My thought was to do something like this:
class length:
#classmethod
def inch_to_foot(cls,inch):
# etc.
#classmethod
def inch_to_meter(cls,inch):
# etc.
I guess you get the idea. Then I would define a dictionary in the class:
from_to={'inch':{'foot':inch_to_foot,'meter':inch_to_meter, ...},
'furlong':{'foot':furlong_to_foot, ...},
#etc
}
So then I think I can write an __init__ method
def __init__(self,num,unit):
cls = self.__class__
setattr(self,unit,num)
for k in cls.from_to[unit].keys:
setattr(self,k,cls.from_to[unit][k](num)
But no go. I get the error "class method not callable". Any ideas how I can make this work? Any ideas for scrapping the whole thing and trying a different approach? Thanks.
If you move the from_to variable into __init__ and modify it to something like:
cls.from_to={'inch':{'foot':cls.inch_to_foot,'meter':cls.inch_to_meter, }}
then I think it works as you expect.
Unfortunately I can't answer why because i haven't used classmethods much myself, but I think it is something to do with bound vs unbound methods. Anyway, if you print the functions stored in to_from in your code vs the ones with my modification you'll see they are different (mine are bound, yours are classmethod objects)
Hope that helps somewhat!
EDIT: I've thought about it a bit more, I think the problem is because you are storing a reference to the functions before they have been bound to the class (not surprising that the binding happens once the rest of the class has been parsed). My advice would be to forget about storing a dictionary of function references, but to store (in some representation of your choice) strings that indicate the units you can change between. For instance you might choose a similar format, such as:
from_to = {'inch':['foot','meter']}
and then look up the functions during __init__ using getattr
E.G.:
class length:
from_to = {'inch':['foot','meter']}
def __init__(self,num,unit):
if unit not in self.from_to:
raise RuntimeError('unit %s not supported'%unit)
cls = self.__class__
setattr(self,unit,num)
for k in cls.from_to[unit]:
f = getattr(cls,'%s_to_%s'%(unit,k))
setattr(self,k,f(num))
#classmethod
def inch_to_foot(cls,inch):
return inch/12.0
#classmethod
def inch_to_meter(cls,inch):
return inch*2.54/100
a = length(3,'inches')
print a.meter
print a.foot
print length.inch_to_foot(3)
I don't think doing with an __init__() method would be a good idea. I once saw an interesting way to do it in the Overriding the __new__ method section of in the classic document titled Unifying types and classes in Python 2.2 by Guido van Rossum.
Here's some examples:
class inch_to_foot(float):
"Convert from inch to feet"
def __new__(cls, arg=0.0):
return float.__new__(cls, float(arg)/12)
class inch_to_meter(float):
"Convert from inch to meter"
def __new__(cls, arg=0.0):
return float.__new__(cls, arg*0.0254)
print inch_to_meter(5) # 0.127
Here's a completely different answer that uses a metaclass and requires the conversion functions to bestaticmethodsrather thanclassmethods-- which it turns into properties based on the target unit's name. If searches for the names of any conversion functions itself, eliminating the need to manually definefrom_totype tables.
One thing about this approach is that the conversion functions aren't even called unless indirect references are made to the units associated with them. Another is that they're dynamic in the sense that the results returned will reflect the current value of the instance (unlike instances of three_pineapples'lengthclass, which stores the results of calling them on the numeric value of the instance when it's initially constructed).
You've never said what version of Python you're using, so the following code is for Python 2.2 - 2.x.
import re
class MetaUnit(type):
def __new__(metaclass, classname, bases, classdict):
cls = type.__new__(metaclass, classname, bases, classdict)
# add a constructor
setattr(cls, '__init__',
lambda self, value=0: setattr(self, '_value', value))
# add a property for getting and setting the underlying value
setattr(cls, 'value',
property(lambda self: self._value,
lambda self, value: setattr(self, '_value', value)))
# add an identity property the just returns the value unchanged
unitname = classname.lower() # lowercase classname becomes name of unit
setattr(cls, unitname, property(lambda self: self._value))
# find conversion methods and create properties that use them
matcher = re.compile(unitname + r'''_to_(?P<target_unitname>\w+)''')
for name in cls.__dict__.keys():
match = matcher.match(name)
if match:
target_unitname = match.group('target_unitname').lower()
fget = (lambda self, conversion_method=getattr(cls, name):
conversion_method(self._value))
setattr(cls, target_unitname, property(fget))
return cls
Sample usage:
scalar_conversion_staticmethod = (
lambda scale_factor: staticmethod(lambda value: value * scale_factor))
class Inch(object):
__metaclass__ = MetaUnit
inch_to_foot = scalar_conversion_staticmethod(1./12.)
inch_to_meter = scalar_conversion_staticmethod(0.0254)
a = Inch(3)
print a.inch # 3
print a.meter # 0.0762
print a.foot # 0.25
a.value = 6
print a.inch # 6
print a.meter # 0.1524
print a.foot # 0.5

How can I define a class in Python?

Quite simple, I'm learning Python, and I can't find a reference that tells me how to write the following:
public class Team {
private String name;
private String logo;
private int members;
public Team(){}
// Getters/setters
}
Later:
Team team = new Team();
team.setName("Oscar");
team.setLogo("http://....");
team.setMembers(10);
That is a class Team with the properties: name/logo/members
Edit
After a few attempts I got this:
class Team:
pass
Later
team = Team()
team.name = "Oscar"
team.logo = "http://..."
team.members = 10
Is this the Python way? It feels odd (coming from a strongly typed language of course).
Here is what I would recommend:
class Team(object):
def __init__(self, name=None, logo=None, members=0):
self.name = name
self.logo = logo
self.members = members
team = Team("Oscar", "http://...", 10)
team2 = Team()
team2.name = "Fred"
team3 = Team(name="Joe", members=10)
Some notes on this:
I declared that Team inherits from object. This makes Team a "new-style class"; this has been recommended practice in Python since it was introduced in Python 2.2. (In Python 3.0 and above, classes are always "new-style" even if you leave out the (object) notation; but having that notation does no harm and makes the inheritance explicit.) Here's a Stack Overflow discussion of new-style classes.
It's not required, but I made the initializer take optional arguments so that you can initialize the instance on one line, as I did with team and team3. These arguments are named, so you can either provide values as positional parameters (as with team) or you can use the argument= form as I did with team3. When you explicitly specify the name of the arguments, you can specify arguments in any order.
If you needed to have getter and setter functions, perhaps to check something, in Python you can declare special method functions. This is what Martin v. Löwis meant when he said "property descriptors". In Python, it is generally considered good practice to simply assign to member variables, and simply reference them to fetch them, because you can always add in the property descriptors later should you need them. (And if you never need them, then your code is less cluttered and took you less time to write. Bonus!)
Here's a good link about property descriptors: http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
Note: Adam Gomaa's blog seems to have disappeared from the web. Here's a link to a saved copy at archive.org:
https://web.archive.org/web/20160407103752/http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/
It doesn't really matter if you specify values as part of the call to Team() or if you poke them into your class instance later. The final class instance you end up with will be identical.
team = Team("Joe", "http://example.com", 1)
team2 = Team()
team2.name = "Joe"
team2.logo = "http://example.com"
team2.members = 1
print(team.__dict__ == team2.__dict__)
The above will print True. (You can easily overload the == operator for Team instances, and make Python do the right thing when you say team == team2, but this doesn't happen by default.)
I left out one thing in the above answer. If you do the optional argument thing on the __init__() function, you need to be careful if you want to provide a "mutable" as an optional argument.
Integers and strings are "immutable". You can never change them in place; what happens instead is Python creates a new object and replaces the one you had before.
Lists and dictionaries are "mutable". You can keep the same object around forever, adding to it and deleting from it.
x = 3 # The name "x" is bound to an integer object with value 3
x += 1 # The name "x" is rebound to a different integer object with value 4
x = [] # The name "x" is bound to an empty list object
x.append(1) # The 1 is appended to the same list x already had
The key thing you need to know: optional arguments are evaluated only once, when the function is compiled. So if you pass a mutable as an optional argument in the __init__() for your class, then each instance of your class shares one mutable object. This is almost never what you want.
class K(object):
def __init__(self, lst=[]):
self.lst = lst
k0 = K()
k1 = K()
k0.lst.append(1)
print(k0.lst) # prints "[1]"
print(k1.lst) # also prints "[1]"
k1.lst.append(2)
print(k0.lst) # prints "[1, 2]"
The solution is very simple:
class K(object):
def __init__(self, lst=None):
if lst is None:
self.lst = [] # Bind lst with a new, empty list
else:
self.lst = lst # Bind lst with the provided list
k0 = K()
k1 = K()
k0.lst.append(1)
print(k0.lst) # prints "[1]"
print(k1.lst) # prints "[]"
This business of using a default argument value of None, then testing that the argument passed is None, qualifies as a Python design pattern, or at least an idiom you should master.
class Team:
def __init__(self):
self.name = None
self.logo = None
self.members = 0
In Python, you typically don't write getters and setters, unless you really have a non-trivial implementation for them (at which point you use property descriptors).
To write classes you would normally do:
class Person:
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
To instantiate instances of a class(es) you would do
person1 = Person("Oscar", 40, "6ft")
person2 = Team("Danny", 12, "5.2ft")
You can also set a default value:
class Person:
def __init__(self):
self.name = "Daphne"
self.age = 20
self.height = "5.4ft"
To instantiate a classes set like this, you want to do:
person3 = Person()
person3.name = "Joe"
person3.age = 23
person3.height = "5.11ft"
You will notice that this method bears a lot of similarity to your typical Python dictionary interaction.

Categories

Resources