Reputation: 25
so for my code, the code should print out two statements, calculating the vectors individually and writing both down. Using my code as an example, the program should print out
Vector: x=4, y=4
Vector: x=3, y=7
However, I am having trouble with creating the class using private attributes, and making a limit of x must be greater than 3 and y cannot be greater than seven. Is the double underscore correct in making it private?
class Vector:
def __init__(self):
self.__x = 4
self.__y =4
v1=Vector(4,4)
print(v1)
v2=Vector(v1.get_x()/2,v1.get_y()*2)
print(v2)
Upvotes: 1
Views: 172
Reputation: 2145
The idiomatic way to do this in Python is something like this:
class Vector:
def __init__(self, x, y):
self._x = x
self._y = y
@property
def x(self):
return self._x
@x.setter
def x(self, value):
if value < 3:
raise ValueError('x must be greater than 3')
self._x = value
@property
def y(self):
return self._y
@y.setter
def y(self, value):
if value > 7:
raise ValueError('y must be less than 7')
self._y = value
def __repr__(self):
return f'Vector(x = {self.x}, y = {self.y})'
v1 = Vector(4, 4)
print(v1)
v2 = Vector(v1.x / 2, v1.y * 2)
print(v2)
Notes on your original code:
x
like v1._x
. Double-underscores does have a meaning, but it's for a different purpose. See https://docs.python.org/3/tutorial/classes.html#private-variables for more details.get_foo
methods. Instead, you should use the @property
decorator (see https://docs.python.org/3/library/functions.html?highlight=property#property). @property
lets you customize "attribute access".__init__
.print(v1)
, but since you didn't define __str__
or __repr__
, this would just print something like <__main__.Vector object at 0x0000019CA15D36A0>
, which isn't very useful.Upvotes: 2
Reputation: 1779
You need to make get
and set
method in Vector
class.
class Vector:
def __init__(self, x, y):
self.__set_x(x)
self.__set_y(y)
def __str__ (self):
return 'vector : '+str(self.__x)+' '+str(self.__y)
def __set_x(self, x):
if x < 3: x = 3
self.__x = x
def __set_y(self, y):
if y >= 7: y = 7
self.__y = y
def get_x(self):
return self.__x
def get_y(self):
return self.__y
v1=Vector(4,4)
print(v1)
v2=Vector(v1.get_x()/2,v1.get_y()*2)
print(v2)
I added some methods to complete implementation.
__str__
returns string
object to be displayed class as the
string
by print(v1)
what you coded.get_x
and get_y
return private
attribute value when you run
v1.get_x()
and v1.get_y()
.__set_x(x)
and __set_y(y)
as private
to
be initialized in constructor only.Upvotes: 1
Reputation: 3807
Regarding the double-underscore. It seems that it works to make it private. I tried it as a test. Maybe it was an update in some newer version of Python than the one I originally studied.
class test_priv():
def __init__(self, x, y):
self.__x = x
self.__y = y
def showvars(self):
print(self.__x, self.__y)
p = test_priv(1,2)
p.showvars()
print(p.__x)
$ python test.py
1 2
Traceback (most recent call last):
File "acid.py", line 12, in <module>
print(p.__x)
AttributeError: 'test_priv' object has no attribute '__x'
Upvotes: 0