Generate Class Instance In Python - python

I have been having trouble getting python to generate a (non-predetermined) number of class instances. Basically have classes be able to reproduce themselves.
class foo:
def __init__(self, name):
self.name = name
while True:
newinstance(foo) #what would the code be for this?
#or maybe
foo.newinstance #just something that could update itself
Basically generate a new instance any number of times. Thanks ahead of time.

This will do what you're asking for, but you'll want to hold onto the values somehow:
while True:
foo(some_name)
This will loop forever, so a more realistic option might be:
names = ["Ned", "Felix", "Guy"]
fooses = [foo(name) for name in names]

Use a list comprehension:
instances_of_foo = [foo("bar") for i in range(number_of_instances)]
Also, if you would like to pass different arguments to each instance, you can create of list of args instead of using range().
list_of_args = [args_for_instance_one, args_for_instance_two,...]
instances_of_foo = [foo(arg) for arg in list_of_args]

Related

How can I use the value of a variable in the name of another without using a dictionary in python?

The answer people have already given for using the value of a variable in the assignment of another is:
to create a dictionary and,
use dict[oldVariable] instead of defining a new one
I don't think that works in the context of what I'm trying to do...
I'm trying to define a class for a vector which would take a list as an input and assign an entry in the vector for each element of the list.
My code looks something like this right now:
class vector:
def __init__(self, entries):
for dim in range(len(entries)):
for entry in entries:
self.dim = entry #here I want to assign self.1, self.2, etc all the way to however
#many elements are in entries, but I can't replace self.dim with
# dict[dim]
def __str__(self):
string = []
for entry in range(1,4):
string.append(self.entry)
print(string)
How do I do this?
What you are doing here is a bit strange, since you are using a variable named "dim" in a for, but you do not do anything with that variable. It looks like you want to use a class as if it was an array... why don't you define an array within the class and access it from the outside with the index? v.elements[1] ... and so on?
Example:
class Vector:
def __init__(self, entries):
self.elements = []
for e in entries:
self.elements.append(self.process(e))
def __str__(self):
buff = ''
for e in self.elements:
buff += str(e)
return buff
Hope this helps.
If I'm reading your question correctly, I think you're looking for the setattr function (https://docs.python.org/2/library/functions.html#setattr).
If you wanted to name the fields with a particular string value, you could just do this:
class vector:
def __init__(self, entries):
for dim in range(len(entries)):
for entry in entries:
#self.dim = entry
setattr(self, str(dict[dim]), dim)
That will result in your object self having attributes named with whatever the values of dict[dim] are and values equal to the dim.
That being said, be aware that an integer value is generally a poor attribute name. You won't be able to do print obj.1 without error. You'd have to do getattr(obj,'1').
I agree with #Ricardo that you are going about this strangely and you should probably rethink how you're structuring this class, but I wanted to directly answer the question in case others land here looking for how to do dynamic naming.

Expressions of Class in python

In one of our homework problems, we need to write a class in python called Gate which contains the drawing and function of many different gates in a circuit. It describes as follows:
in1 = Gate("input")
out1 = Gate("output")
not1 = Gate("not")
Here in1, out1, not1 are all instances of this class. What do the ("input") ("output") ("not") mean? are they subclass or something?
We are only told that when we define a class using:
class Gate(object)
when we make an instance we use:
in1 = Gate()
I haven't seen stuff inside a () after the class name, how to understand that?
Taking into account that you pass strings as a parameter I would suggest that it is just a parameter like:
class Gate:
def __init__(self, param1):
self.param1 = param1
var1 = Gate("hello")
print var1.param1
# expected output:
# hello
To be able to say how the class Gate works one has to look into it.
What is in1 = Gate("input") this?
In short this Gate("input") is a constructor call def init.
Use for create object.
Gate() and Gate("some value") both are constructor but
1). Gate() Create a object without initialize value to particular attributes of this object.
2). Gate('some value') Create a object with a value.
And i think you need to work on some basic concept of OOPS.

Python: Copy two dependent lists together with their dependence

I am stuck with some problem which I guess is not very difficult, but I could not find any answer to it.
I have two lists of objects, each of them containing lists of objects in the other. I would like to copy them both to do come tests and evaluate the results before repeating the process. In the end, I would keep the best result.
However, when copying each lists, the result is, unsurprisingly, not two dependent lists but two lists which do not interact anymore. How can I solve this? Is there some proper way to do it?
Given the two classes defined as follow.
import copy
class event:
def __init__(self, name):
self.name = name
self.list_of_persons = []
def invite_someone(self, person):
self.list_of_persons.append(person)
person.list_of_events.append(self)
class person:
def __init__(self, name):
self.name = name
self.list_of_events = []
I tried to write some simple example of the situation I am facing. The print function shows that the objects identifiers are different in the two lists.
# Create lists of the events and the persons
the_events = [event("a"), event("b")]
the_persons = [person("x"), person("y"), person("z")]
# Add some persons at the events
the_events[0].invite_someone(the_persons[0])
the_events[0].invite_someone(the_persons[1])
the_events[1].invite_someone(the_persons[1])
the_events[1].invite_someone(the_persons[2])
print("Original :", id(the_persons[1]), id(the_events[0].list_of_persons[1]), id(the_events[1].list_of_persons[0]))
# Save the original configuration
original_of_the_events = copy.deepcopy(the_events)
original_of_the_persons = copy.deepcopy(the_persons)
for i in range(10):
# QUESTION: How to make the following copies?
the_events = copy.deepcopy(original_of_the_events)
the_persons = copy.deepcopy(original_of_the_persons)
print(" i =", i, ":", id(the_persons[1]), id(the_events[0].list_of_persons[1]), id(the_events[1].list_of_persons[0]))
# Do some random stuff with the two lists
# Rate the resulting lists
# Record the best configuration
# Save the best result in a file
I thought about using some dictionary and make the list independent, but that would imply a lot of code revision which I would like to avoid.
Thank you in advance for any help! I am new both to Python and StackExchange.
Since deepcopy makes copies of all underlying objects of the thing being copied, doing two independent calls to deepcopy breaks your links between objects. If you create a new object with references to both of these things (like a dict) and copy that object, that will preserve the object references.
workspace = {'the_persons': the_persons, 'the_events': the_events}
cpw = copy.deepcopy(workspace)

Python: how to automatically create instance object?

I want to create instance objects automatically as I explained in the following:
Class MyClass:
def __init__(self,x):
self.x = x
list = ["A","B"]
I want to create the following but automatically, means to loop through the list and create identical object for each element:
A = MyClass(text)
B = MyClass(text)
e.g. like the following which doesn't work:
# this doesn't work but explains more what I need
for i in list:
i = MyClass(text)
Thanks to all of your help!
In general, you can't and shouldn't shove things into your namespace like that. It's better to store those instances in a dict or a list
Class MyClass:
def __init__(self,x):
self.x = x
lst = ["A","B"] # don't use list as an identifier
myclasses = {k: MyClass(text) for k in lst}
Now your instances are
myclasses['A'], myclasses['B'] etc.
If you really want to create a handful of variables in your namespace:
A, B = (MyClass(text) for x in range(2))
note that this means you need to be explicit. You can't get the A,B from a file or user input etc.
Don't be tempted to use exec to pull this off. It's probably the wrong way to go about solving your problem. Tell us why you think you need to do it instead.

Python - Proper way of serially reassign/update class members

I have a class whose members are lists of numbers built by accumulating values from experimental data, like
class MyClass:
def __init__(self):
container1 = []
container2 = []
...
def accumulate_from_dataset(self,dataset):
for entry in dataset:
container1.append( foo (entry) )
container2.append( bar (entry) )
...
def process_accumulated_data(self):
'''called when all the data is gathered
'''
process1(container1)
process2(container2)
...
Issue: it would be beneficial if I could convert all the lists into numpy arrays.
what I tried: the simple conversion
self.container1 = np.array(self.container1)
works. Although, if I would like to consider "more fields in one shot", like
lists_to_convert = [self.container1, self.container2, ...]
def converter(lists_to_convert):
for list in lists_to_convert:
list = np.array(list)
there is not any effective change since the references to the class members are passed by value.
I am thus wondering if there is a smart approach/workaround to handle the whole conversion process.
Any help appreciated
From The Pragmatic Programmer:
Ask yourself: "Does it have to be done this way? Does it have to be done at all?
Maybe you should rethink your data structure? Maybe some dictionary or a simple list of lists would be easier to handle?
Note that in the example presented, container1 and container2 are just transformations on the initial dataset. It looks like a good place for list comprehension:
foo_data = [foo(d) for d in dataset]
# or even
foo_data = map(foo, dataset)
# or generator version
foo_data_iter = (foo(d) for d in dataset)
If you really want to operate on the instance variables as in the example, have a look at getattr and hasattr built-in functions
There isn't an easy way to do this because as you say python passes "by-reference-by-value"
You could add a to_numpy method in your class:
class MyClass:
def __init__(self):
container1 = []
container2 = []
...
def to_numpy(self,container):
list = self.__getattr__(container)
self.__setattr__(container,np.array(list))
...
And then do something like:
object = MyClass()
lists_to_convert = ["container1", "container2" ...]
def converter(lists_to_convert):
for list in lists_to_convert:
object.to_numpy(list)
But it's not very pretty and this sort of code would normally make me take a step back and think about my design.

Categories

Resources