How super() works with private variables? - python-3.x

There is an interesting question on python 3.5. For example I've smth like:
class A:
__x = 0
def __init__(self, x):
self.__x = x
def set_x(self,x): __x=x
def get_x(self): return x
class B(A):
__y = 0
def __init(self, x, y)
self.__y = y
super(B, self).__init__(x)
def set_y(self,y): __y=y
def get_y(self): return y
def toString(self): return "x = {} and y = {}".format(self.__x,
self.__y);
test = B(7,3)
test.toString()
Why do I have an error here: "B object has no attribute _B__x", if the method super() let me to use all methods of parante class?
Sure, if I write, like:
def toString(self): return "x = {} and y = {}".format(self.get_x(),
self.__y);
It works well!

You do not get access to private variables/members through super().
So in order to access B.__x, you will have to do
def toString(self): return "x = {} and y = {}".format(self._B__x,
self.__y);

Related

AttributeError: 'obj_2' object has no attribute 'var_1' - getattr -

I need to get data to second class from first class.
I Used - getattr - function to do it.
class obj_1:
def __init__(self):
self.var_1 = 'Hello'
self.var_2 = 'World'
def get_id(self):
i = self.var_1
j = self.var_2
return i, j
def vw(self):
print('Hello..')
class obj_2:
def __init__(self):
pass
def r_data(self):
print('called r_data')
x, y = getattr(obj_1, "get_id")(self)
print('x > ', x)
print('y > ', y)
def rd(self):
getattr(obj_1, 'vw')(self)
if __name__ == '__main__':
ob = obj_2()
ob.r_data()
It given error as - AttributeError: 'obj_2' object has no attribute 'var_1'
I think you are getting this error since the function get_id uses attributes of the class, i.e self.var_1 self.var_2
and these attributes are never initialized since the __init__ function was never called (and since you cant have attributes without an actual object )
so to fix your code I would create an object of "obj_1" and call the function
"get_id" with that object
class obj_1:
def __init__(self):
self.var_1 = 'Hello'
self.var_2 = 'World'
def get_id(self):
i = self.var_1
j = self.var_2
return i, j
def vw(self):
print('Hello..')
class obj_2:
def __init__(self):
self.o1 = obj_1()
def r_data(self):
print('called r_data')
x, y = self.o1.get_id()
print('x > ', x)
print('y > ', y)
def rd(self):
getattr(obj_1, 'vw')(self)
if __name__ == '__main__':
ob = obj_2()
ob.r_data()
hope i could help, please let me know in the comments if you didn't understand anything.
and if my comment helped you i would relly appreciate marking this comment as the answer :)

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)

i have made an module to add two integer, but calling it gives me "none" answer

I'm beginner and learning to code,
Here is Module:
class extfile:
def add(x, y):
return x + y
Here is the Program:
class A:
def a(x, y):
extfile.add(x,y)
print(A.a(4,5))
Here is the Output:
None
Your class A's method a is not returning anything:
class extfile:
def add(x, y):
return x + y
class A:
def a(x, y):
return extfile.add(x,y)
print(A.a(4,5))
#output: 9

Python: How can I call the vairables of a member method from another method in the same class?

I am trying to refer to variables (x1,x2,x3,x4) of a member function (distance) inside another method (slope) within the same class. However, it's throwing an error. What am I doing wrong?
class Line():
def __init__ (self,cor1,cor2):
self.cor1 = cor1
self.cor2 = cor2
def distance(self):
x1 = self.cor1[0]
y1 = self.cor1[1]
x2 = self.cor2[0]
y2 = self.cor2[1]
return math.sqrt((x2-x1) ** 2 + (y2-y1) ** 2)
def slope(self):
return (self.y1-self.y2)/(self.x1-self.x2)
I tried moving it to the init method and it works. The following code works for me. However, is there a way to call x1,x2,y1,y2 which are variables of one method from another?
class Line():
def __init__ (self,cor1,cor2):
self.cor1 = cor1
self.cor2 = cor2
self.x1 = self.cor1[0]
self.y1 = self.cor1[1]
self.x2 = self.cor2[0]
self.y2 = self.cor2[1]
def distance(self):
return math.sqrt((self.x2-self.x1) ** 2 + (self.y2-self.y1) ** 2)
def slope(self):
return (self.y1-self.y2)/(self.x1-self.x2)
No, you cannot do that; further, the use of global variables is not recommended inside classes.
Your OOP design could use a class Point to represent a pair of coordinates; that class should also hold the distance method.
In the following example, I added a length method to the class LineSegment, as a property, so you can access it like an attribute:
class Point:
"""represents a pair of coordinates
"""
def __init__(self, x, y):
self.x = x
self.y = y
def distance(self, other):
return ((other.x - self.x)**2 + (other.y - self.y)**2)**.5
class LineSegment:
"""represents a line segment with its start and end Point
"""
def __init__ (self, start, end):
self.start = start
self.end = end
def slope(self):
denom = (self.start.x - self.end.x)
return (self.start.y - self.end.y) / (self.start.x - self.end.x) if denom else float('inf')
#property
def length(self):
return self.start.distance(self.end)
cor1 = Point(1, 2)
cor2 = Point(3, 4)
line = LineSegment(cor1, cor2)
print(line.slope(), line.length)

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.

Resources