Passing list as an argument to a class - python-3.x

There is a simple class to create a representation of a polynomial (args are ints here):
class MyPolynomial:
def __init__(self, *args):
self.numbers = [x for x in args]
I want to create a method able to create a new polynomial, but the argument is a list, so it would work like this:
MyPolynomial.from_iterable([0, 1, 2]) == MyPolynomial(0, 1, 2)
How do I handle a list to pass it as int arguments?

You can do this:
class MyPolynomial:
def __init__(self, *args):
self.numbers = [x for x in args]
#classmethod
def from_iterable(cls, the_list):
# return instance of this class
return cls(*the_list)

Related

Class Inheritance for the parent __int__ in Python

My code is provided in the end. I want to let the class general inherit all the variables of the constructor (_ init _) in the class LDA. It seems that when the method X_F in the class general calls the X_c, it just returns the objective rather than the array of np.random.rand(3,2) generated in the main. I tried to let the method X_F print the value of the variable m, but the printed result is a default value of 3, rather than 10.
class LDA:
def __init__(self, X_c, m = 3, K=1):
self.X_c =X_c
self.m =m
self.K = K
def Squared_L2_loss(self):
X_result = general(self).X_F()
return X_result
class general(LDA):
def X_F(self):
X = self.X_c[0]
print(self.m)
return X.T
if __name__ == '__main__':
X_c=np.random.rand(3,2)
X = LDA(X_c, m=10, K=30)

Creating a child class from a parent method in python

I am trying to make a class that has a bunch of children that all have their own respective methods but share common methods through the parent. The problem is I need to create an instance of the child class in the parent method but am not sure how to go about it
my code so far looks like this
def filterAttribute(self, attribute, value):
newlist = []
for thing in self._things:
if thing._attributes[attribute] == value:
newlist.append(thing)
return self.__init__(newlist)
the class constructor takes in a list as its sole argument. Does anyone know if there is a standard way of doing this because my code is returning a NoneType object
Here are a few examples of classes I have made
This is the parent class:
class _DataGroup(object):
def __init__(self, things=None):
self._things=things
def __iter__(self):
for x in self._things:
yield x
def __getitem__(self, key):
return self._things[key]
def __len__(self):
return len(self._things)
def extend(self, datagroup):
if(isinstance(datagroup, self.__class__)):
self._things.extend(datagroup._things)
self._things = list(set(self._things))
def filterAttribute(self, attribute, value):
newlist = []
for thing in self._things:
if thing._attributes[attribute] == value:
newlist.append(thing)
#return self.__init__(newlist)
return self.__init__(newlist)
this is one of the child classes
class _AuthorGroup(_DataGroup):
def __init__(self, things=None):
self._things = things
def getIDs(self):
return [x.id for x in self._things]
def getNames(self):
return [x.name for x in self._things]
def getWDs(self):
return [x.wd for x in self._things]
def getUrns(self):
return [x.urn for x in self._things]
def filterNames(self, names, incl_none=False):
newlist = []
for thing in self._things:
if((thing is not None or (thing is None and incl_none)) and thing.name in names):
newlist.append(thing)
return _AuthorGroup(newlist)
The functionality I am looking for is that I can use the parent class's with the child classes and create instances of the child classes instead of the overall DataGroup parent class
So if I correctly understand what you are trying to accomplish:
You want a Base Class 'DataGroup' which has a set of defined attributes and methods;
You want one or mpore child classes with the ability to inherit both methods and attributes from the base class as well as have the ability to over-ride base class methjods if necessary: and
You want to invoke the child class without also having to manually invoke the base class.
If this in fact is your problem, this is how I would proceed:
Note: I have modified several functions, since I think you have several other issues with your code, for example in the base class self._things is set up as a list, but in the functions get_item and filterAttribute you are assuming self._things is a dictionary structure. I have modified the functions so all assume a dict structure for self._things
class _DataGroup:
def __init__(self, things=None):
if things == None:
self._things = dict() #Sets up default empty dict
else:
self._things=things
def __iter__(self):
for x in self._things.keys():
yield x
def __len__(self):
return len(self._things)
def extend(self, datagroup):
for k, v in datagroup.items():
nv = self._things.pop(k, [])
nv.append(v)
self._things[k] = nv
# This class utilizes the methods and attributes of DataGroup
# and adds new methods, unique to the child class
class AttributeGroup(_DataGroup):
def __init__(self, things=None):
super.__init__(things)
def getIDs(self):
return [x for x in self._things]
def getNames(self):
return [x.name for x in self._things]
def getWDs(self):
return [x.wd for x in self._things]
def getUrns(self):
return [x.urn for x in self._things]
# This class over-rides a DataGroup method and adds new attribute
class NewChild(_DataGroup):
def __init__(self, newAttrib, things = None):
self._newattrib = newAttrib
super.__init__(self, things)
def __len__(self):
return max(len(self._newattrib), len(self._things))
These examples are simplified, since I am not absolutely sure of what you really want.

Change Return Value of Class Instance

How can I overwrite a class with one of its attributes?
e.g.
class AListGenerator(list):
def __init__(self, *args):
self._mylist = [word for word in args if 'a' in word]
self = self._mylist # does nothing
>>> x = AListGenerator('mum', 'dad', 'mike', 'aaron')
>>> x
[]
>>> x._mylist
['dad', 'aaron']
How can I make x return x._mylist, so that there's no need to call the _mylist attribute?
>>> x
['dad', 'aaron']
To clarify, I do not want/need a __repr__, I want to be able to do stuff like:
x.append('ryan') and x returning ['dad', 'aaron', 'ryan'], and not just ['ryan'].
You are inheriting from list, so all its methods are already accessible in your class, so you already can do x.append(stuff).
You should (probably always) initiate the base class before doing anything in your __init__ method:
class Stuff(list):
def __init__(self, *args):
# initiate the parent class!
super().__init__(word.lower() for word in args)
# you also can define your own attributes and methods
self.random_ID = 5 # chosen by fair dice roll, guaranteed to be random
x = Stuff("HELLO", "WoRlD")
And then you can print x and do with it everything you can do with a list.

How to pass property methods as arugments in Python

First, let's consider this working example using get and set methods for the variable x
class Foo:
def __init__(self):
self._x = 0
def set_x(self, x):
self._x = x
def get_x(self):
return self._x
class Bar:
def __init__(self, set_method):
self._set_method = set_method
def set_x(self, x):
self._set_method(x)
f = Foo()
f.set_x(5)
print(f.get_x())
# Prints 5
b = Bar(f.set_x)
b.set_x(10)
print(f.get_x())
# Prints 10
As you can see I pass the possibility to set the variable x of the instance f of class Foo, to the instance b of class Bar.
Now, I would like to do the same, but with property decorators instead, roughly like this
class Foo:
def __init__(self):
self._x = 0
#property
def x(self):
return self._x
#x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self._x_property = x_property
def set_x(self, x):
self.x_property = x
f = Foo()
f.x = 5
print(f.x)
# Prints 5
b = Bar(f.x)
b.set_x(10)
print(f.x)
# Prints 5
What happens is that the value 5, instead of the property, gets passed to instance b, meaning that b can't access x in instance f. Is there a nice way to solve this?
I would then also like to do the same thing for the get method. In the first code that requires me to pass both methods, but if there is a way to get the second code to work I would hopefully only have to pass on the property which I then can set and get as a normal variable.
I would really want to use the property decorators or similar as it cleans up my code a lot. I use python 3.5.2.
Thanks,
Andreas
You can accomplish this by accessing the fset attribute of Foo.x. Note the use of class-dot notation rather than instance-dot. fset takes two arguments: the instance to access and the value to write. Here is a working example
class Foo:
#property
def x(self):
return self._x
#x.setter
def x(self, x):
self._x = x
class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, foo, value):
self.x_property(foo, value)
f = Foo()
f.x = 5
print(f.x)
b = Bar(Foo.x.fset)
b.set_x(f, 10)
print(f.x)
Notice that we had to pass f to set_x because we need it to invoke the setter. You could eliminate the f param by using partial from the functools module to bind f to the property setter. Pass the partial binding in to the constructor of Bar.
class Bar:
def __init__(self, x_property):
self.x_property = x_property
def set_x(self, value):
self.x_property(value)
f = Foo()
b = Bar(partial(Foo.x.fset, f))
b.set_x(10)
print(f.x)
It might be wise to rename x_property and this point. It is really just a function as far as Bar is concerned. It wouldn't have to be a property.

How do I define a variable for all class methods use?

I need to define a variables that is to be used in all the methods of one class.
class A:
def method1(self):
for i in range(N):
*do something with M*
def method2(self):
for i in range(N):
*do other thing with M*
and so on.
All I need to do is define N and M variables somewhere in the begining of class describing. I tried to define it in constructor like this:
class A:
def __init__(N, M):
self.N=N
self.M=M
def method1(self):
...
in tend to call A with this parameters just once. But there was another error in case I don't really now how to use constructor for now. Then I add this variables as parameters of each method:
...
def method1(self, N, M):
...
And that time it worked perfectly. But I don't want to input values each time I call A.methodX() and I'm 100% sure there is one or two ways that accords my requests.
You were on the right track so I wrote a short version of what I suspect you wanted to do with a little 'debug' code embedded. Note the instantiation of the class aa = A(1,2)
class A:
def __init__(self, N, M):
self.N = N
self.M = M
def method1(self):
print ("iterate N")
for i in range(self.N):
print (str(i) + "\n")
def method2(self):
print ("iterate M")
for i in range(self.M):
print (str(i) + "\n")
aa = A(1, 2)
aa.method1()
aa.method2()
Note that what I've done here is create instance variables - you can also create class variables by instantiating them outside of the methods. So iVar becomes the class variable.
class A:
iVar = 0
def __init__(self, N, M):
self.N = N
self.M = M
......

Resources