How do I define a variable for all class methods use? - python-3.x

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
......

Related

Ensure a class always uses its own version of a method rather than the one defined in a subclass?

I have this code:
class A:
def __init__(self, vals: list):
self._vals = vals
def __len__(self) -> int:
# some side effects like logging maybe
return len(self._vals)
def print_len(self) -> None:
# some function that uses the len above
print(len(self))
class B(A):
def __len__(self) -> int:
return 0
The issue is, I want print_len to always call A.__len__. I can do this:
class A:
def __init__(self, vals: list):
self._vals = vals
def __len__(self) -> int:
return len(self._vals)
def print_len(self) -> None:
print(A.__len__(self))
class B(A):
def __len__(self) -> int:
return 0
But it feels wrong. Basically I want B to lie about __len__ to outside callers, but internally use the correct len specified in A.
So
a = A([1, 2, 3])
print(len(a)) # print 3
a.print_len() # print 3 - no surprises there
b = B([1, 2, 3])
print(len(b)) # print 0 - overload the __len__
b.print_len() # want this to be 3 using A's __len__, not 0 using B's __len__
Is there any way to ensure a class always uses its own version of a method rather than a subclass' version? I thought name mangling of dunder methods would help here.
I think your approach is a good one. The zen of Python states that "There should be one-- and preferably only one --obvious way to do it." and I think you've found it.
That being said, you can do this via name mangling. You just need to prefix the method with double underscores (don't add them to the end like magic methods). This will create a private method which won't ever be overwritten by subclasses.
I think this might be self-defeating since you're now putting the computation in a different method.
class A:
def __init__(self, vals: list):
self._vals = vals
def __len__(self) -> int:
return self.__length()
def __length(self) -> int:
return len(self._vals)
def print_len(self) -> None:
print(self.__length())

Simplest way to multithread using class variables?

I'm trying to implement a function in my class that calculates information from array A and outputs the result in array B. Array A and array B are both variables of a class, as is the function. Something along these lines:
class MyClass:
def __init__(self, A):
self.A = A
self.B = np.zeros((A.shape[0], A.shape[1])
def my_function(self, i):
self.B += self.A[i]
def main(self):
for i in range(A.shape[2]):
my_function(i)
example = np.random.rand(256, 256, 1000)
my_class = MyClass(example)
my_result = my_class.B
Obviously this function is oversimplified but the question revolves about how to use multiprocess with variables self.A and self.B. I've tried something like this but it didn't work at all:
class MyClass:
def __init__(self, A):
self.A = A
self.B = np.zeros((A.shape[0], A.shape[1])
def my_function(self, i):
return self.A[i]
def main(self):
with multiprocessing.Pool() as p:
position = range(self.A.shape[2])
for i, result in enumerate(p.map(my_function, position))
self.B += result
You can get your example code to work doing something like...
class MyClass:
def __init__(self, A):
self.A = A
self.B = np.zeros((A.shape[0], A.shape[1]))
def my_function(self, i):
return self.A[:,:,i]
def run(self):
with Pool() as p:
position = range(self.A.shape[2])
for result in p.imap(self.my_function, position, chunksize=self.A.shape[2]):
self.B += result
example = np.random.rand(256, 256, 1000)
my_class = MyClass(example)
st = time.time()
my_class.run()
print(time.time() - st)
The problem with multiprocessing is that it has to fork new processes and then serialize (via pickle) the data going into and out of them. For simple code like this, the overhead is much more than the actual function you're completing.
Setting chunksize to the size of your iterable is just a way to assure that python doesn't fork process pools more than once and thus reduce the overhead. For this example the multiprocessed code is still slower than doing it single process, however if you have a more complex function, the MP version could be faster.
As a general rule, I try to never put the multiprocessed function/data inside of the class. This leads to a lot of extra overhead in the fork/pickle/unpickle process. You can move your function outside with something like...
# Simple gobal data / function
data = None
def my_function(i):
global data
return data[:,:,i]
class MyClass:
def __init__(self, A):
global data
data = A # move class data to global
self.A = A
self.B = np.zeros((A.shape[0], A.shape[1]))
def run(self):
with Pool() as p:
position = range(self.A.shape[2])
for result in p.imap(my_function, position, chunksize=self.A.shape[2]):
self.B += result
example = np.random.rand(256, 256, 1000)
my_class = MyClass(example)
st = time.time()
my_class.run()
print(time.time() - st)
For a simple function like this multiprocessing will still be slower, but if your actual function has a lot of complexity this can speed things up.

How to increment Methods within a Class?

I would like to increment methods within a python class but I don't know how to do it. Code will be easier to understand than words so here it is...
I do this because I want to use the methods later. I've tried first to create an incremental list of functions that I could use later, but it doesn't work. this is why I'm trying to do it this way.
What I would like as a result -> Works:
class MyClass:
def __init__(self, val):
self.value = val
def method_1(self):
print(self.value * 1)
def method_2(self):
print(self.value * 2)
def method_3(self):
print(self.value * 3)
def method_4(self):
print(self.value * 4)
mc = MyClass(5)
mc.method_1()
mc.method_2()
mc.method_3()
mc.method_4()
What I would like as a way to write it -> Doesn't work:
class MyClass:
def __init__(self,val):
self.value = val
for i in range(0,5):
def method_i(self):
print(self.value * (i + 1))
mc = MyClass(5)
mc.method_1()
mc.method_2()
mc.method_3()
mc.method_4()
This is possible, but not advisable:
class MyClass:
def __init__(self, val):
self.value = val
for i in range(5):
def method_xxx(self, i=i): # avoid late binding problem
print(self.value * (i + 1))
# Correct names:
method_xxx.__name__ = method_xxx.__name__.replace("xxx", str(i + 1))
method_xxx.__qualname__ = method_xxx.__qualname__.replace("xxx", str(i + 1))
# bind to class:
setattr(MyClass, "method_{}".format(i + 1), method_i)
Because interpolation is not really possible, we need to define the method under a different name first (if we want to avoid eval & Co.). Definition outside the class itself is necessary because the class body is executed before the class is created, so its name is not available yet.
Instead, it's a much better idea to just give the number as an argument to a more general method:
class MyClass:
...
def method(self, i):
print(self.value + i)
The short answer is that you should not. It is not advisable to use variable numbering instead of, say, lists.
If the methods are indeed all doing the same thing up to a parameter, you probably want to make this a single method.
class MyClass:
...
def method(self, i):
print(self.value * i)
If the method have a no recognizable pattern, then you will need to define them anyway.

How to use two instances of a base class from a derived class

I want to use two instances of a base class from one derived class. I am not sure if the following code is technically correct or if there is a better way. Can the two instances mix up in any situation?
The base class A is intended to perform a common task: "changevar" which changes the variable "var" to "dv". The derived class B use this method but with two variables "var1", "var2" to change it to "dv1", and "dv2" respectively. class B then performs an "operation" over the changed variables "var1", and "var2" and return the result (in this case multiply).
test.py:
class A:
def __init__(self, var):
self.var = var
def changevar(self, dv):
self.var = self.var + dv
def getvar(self):
return self.var
class B(A):
def __init__(self, var1, var2):
self.var1 = var1
self.var2 = var2
A.__init__(self, var1)
self.inst1 = A(self.var)
A.__init__(self, var2)
self.inst2 = A(self.var)
def operation(self):
dv1 = 2
dv2 = -2
self.inst1.changevar(dv1)
self.inst2.changevar(dv2)
self.var1 = self.inst1.getvar()
self.var2 = self.inst2.getvar()
return self.var1, self.var2, self.var1 * self.var2
def main():
test = B(10, 10)
v1, v2, v3 = test.operation()
print (v1, v2, v3)
return
if __name__ == "__main__":
main()```
>>>python3 test.py
>>>12 8 96
In your code, you're not actually using the inheritance.
When you execute self.inst1 = A(self.var) you are creating a whole new instace of A, which is different from that which is the base for your B, and assigning it to a field.
Good news are: you don't need inheritance in your case. what you need (and de-facto do) is composition - having fields of type A in your type B.
Just remove A as a base from B at all, and use the inner fields of this type, the result will be the same:
class A:
def __init__(self, var):
self.var = var
def changevar(self, dv):
self.var = self.var + dv
def getvar(self):
return self.var
class B:
def __init__(self, var1, var2):
self.inst1 = A(var1)
self.inst2 = A(var2)
def operation(self):
dv1 = 2
dv2 = -2
self.inst1.changevar(dv1)
self.inst2.changevar(dv2)
var1 = self.inst1.getvar()
var2 = self.inst2.getvar()
return var1, var2, var1 * var2
def main():
test = B(10, 10)
v1, v2, v3 = test.operation()
print (v1, v2, v3)
return
if __name__ == "__main__":
main()
Inheritance should be used when you want to use instances of type B as if they were of type A (e.g., call A's methods on instances of type B).
Generally we say that B should inherit from A, ib B "is-a" A - e.g. a Dog is an Animal, a Square is a Shape.
Composition is more of "has-a" relationship, like a Car has a Radio
I hope I made it clear, it's a little hard to grasp that reasoning with meaningless class names like A and B :)

call a method of a class in another method in that same class in python

how i can call a method in a class to another method in that same class in python3?
class foo
def method1(self):
return something
def method2(self):
print(method1())
my actual code is :
class MSD:
#it find maximum shared divisible of two number
def __init__(self,firstNumber1,secondNumber1):
self.firstNumber=firstNumber1
self.secondNumber=secondNumber1
def alldivisible(self):
__all_divisible_list1 =[]
__all_divisible_list2=[]
for i in range(1, int(self.firstNumber)+1):
if self.firstNumber % i == 0:
__all_divisible_list1 = __all_divisible_list1+[i]
for i in range(1, int(self.secondNumber)+1):
if self.secondNumber % i == 0:
__all_divisible_list2 = __all_divisible_list2 + [i]
common_divisible_list = set(__all_divisible_list1) & set(__all_divisible_list2)
return max(common_divisible_list)
class fractionStuff:
def __init__(self,first_fraction1,secound_fraction1):
self.firstFraction=((first_fraction1)).split("/")
self.secoundFraction=((secound_fraction1).split('/'))
def sumCalculate(self):
print()#HERE
here i wanna find divisible of two numbers which i wanna define.
what i must do? i need write my function out of class?
The self reference is required:
class Foo:
def method1(self):
return "something"
def method2(self):
print(self.method1())
All access to the members of a class is through the self parameter. That's not just attribute variables, it's methods as well.
print(self.method1())

Resources