Python Forum
the best way to handle the class "value" - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: the best way to handle the class "value" (/thread-11705.html)



the best way to handle the class "value" - Levitanus - Jul-22-2018

Hi, I'm sorry for my noobies beforehand.

I'm trying to make an API to code generation, so some "variable objects" has to have behavior close to normal python vars just to avoid extra-typing of end-user.
With standard methods overriding all is fine, but in case of retrieving the value, or assigning it I found some "syntax" problems.

For example, the first redaction used __call__ method as sort of descriptor. so, syntax looked:
> my_var()
val
> my_var(1)
> my_var()
1
but it starts to be uncomfortable with usage of callable() and seemed functions.
Also, things start to be ambiguous for such cases:
> var2(1)
> var2 += 1
# here we can use methods of var2
> var1(var2)
> var1()
2
# here we can NOT use methods of var2
var1(var2())
and it was not so good to handle inside values of variables but not references to variables themselves in some cases.
So, with the new version, I'm looking to descriptors, but even with first "callable" problem solved I found the second problem alive.
Example:
> var1.val = 1
> var2.val = 2
> var2 += var1
> var2.val
3
# nasty
> var2.val = var1
> var2.val
1
How would You solve this case?

more than, with descriptors, there is no "syntax-defense" of making something terrible:
var1.val = 1
var2.val = 2
var1.val = var2

# here code is being generated
var1 += 1

# here wrong code is being generated
var1 = var2
var1 += 1

# here no code is generated
var1 = var2.val
var1 += 1



RE: the best way to handle the class "value" - Levitanus - Jul-22-2018

well, I thought a bit and decided not to use <<= operator in the generator, cause it is not used by target language.
so now it looks pretty 'syntax-safe':
class Test:

    def __init__(self, val, name):
        self._val = val
        self._name = name
        self.named = False

    def __ilshift__(self, other):
        if hasattr(other, 'val'):
            other = other.val
        self.set(other)
        return self

    def __rlshift__(self, other):
        return self.get()

    def set(self, val):
        self._val = val

    def get(self):
        if self.named:
            return self._name
        return self._val

    @property
    def val(self):
        return self._val


x = Test(1, 'x')
y = Test(2, 'y')

print('x.val =', x.val)
print('y.val =', y.val)

x <<= y
print('x.val =', x.val)
z: int = None
z <<= x
print('z =', z)
x <<= 3
y <<= x
print('y.val =', y.val)
y.val = 4
Output:
x.val = 1 y.val = 2 x.val = 2 z = 2 y.val = 3 Traceback (most recent call last): File "E:\packages\pyksp\pyksp\compiler2\simple_test.py", line 45, in <module> y.val = 4 AttributeError: can't set attribute