Manipulating Python Magic Methods

Manipulating Python Magic Methods



I have more of a background with data science libraries or calling methods and attributes from classes. I am experimenting with manipulating magic methods. I am having a difficult time getting bool types and returning their opposites.


bool



I did something with str and datetime objects that worked but can't seem to to the same with __cmp__, __lt__, __eq__ or `gt'. Here is my code:


str


datetime


__cmp__


__lt__


__eq__


class Opposite:

def __cmp__(self, other):

if other.__class__.__name__ == 'bool':
return other

def __lt__(self, other):
if other.__class__.__name__ == 'bool':
return other

def __eq__(self, other):
if other.__class__.__name__ == 'bool':
return other

def __gt__(self, other):
if other.__class__.__name__ == 'bool':
return other


if __name__=="__main__":

""" test class Compare """

a = 1
b = 1
c = a < b
d = a > b
e = a == b

print("Results:natnbtnctndtnetn".format(a,b,c,d,e))
print("nType:na-typetnb-typetnc-typetnd-typetne-typetn"
.format(type(a),type(b),type(c),type(d),type(e)))



This prints the following:


Results:
a 1
b 1
c False
d False
e True

Type:
a-type <class 'int'>
b-type <class 'int'>
c-type <class 'bool'>
d-type <class 'bool'>
e-type <class 'bool'>



As you can see, the results are the same as not using the class at all. I added an __init__ method to print using Opposite and it only prints that if I instantiate the object with something like a = Opposite().


__init__


using Opposite


a = Opposite()



I would like to enter something like a > b, a < b, or a == b, and return the opposite boolean value, True, or False, as an exercise.


a > b


a < b


a == b


True


False



I tried several things such as placing the methods under the __init__ method I created, which didn't work either. I read on this and still don't quite understand how to do this with booleans, integers and floats for that matter. The way the methods are above is how I was able to turn datetime objects into strings with __add__, __radd__ and __rsub__ methods.


__init__


__add__


__radd__


__rsub__



Thank you for your help.



EDIT



Thanks to your help, I have a better understanding and have completed my small experiment with this code:


class Opposite:

def __init__(self, x):
self._x = x

def __lt__(self, other):
return not self._x < other._x

def __eq__(self, other):
return not self._x == other._x

def __gt__(self, other):
return not self._x > other._x

def __le__(self, other):
return not self._x <= other._x

def __ge__(self, other):
return not self._x >= other._x

def tester(w, x, y, z):
try:
# Original values
a = w < x
b = w > x
c = w == x
d = w <= x
e = w >= x

# Opposite values
f = y < z
g = y > z
h = y == z
i = y <= z
j = y >= z

# Results
k = 'Fail' if a == f else 'Success'
l = 'Fail' if b == g else 'Success'
m = 'Fail' if c == h else 'Success'
n = 'Fail' if d == i else 'Success'
o = 'Fail' if e == j else 'Success'

print('nComparing and :t<t>t==t<=t>='.format(w, x))
print('Original Values:', end='t')
print('0t1t2t3t4'.format(a, b, c, d, e))
print('Opposite Values:', end='t')
print('0t1t2t3t4'.format(f, g, h, i, j))
print('Comparisons:', end='t')
print('t0t1t2t3t4'.format(k, l, m, n, o))

except(Exception) as err:
print(err)

if __name__=="__main__":

""" test class Compare """

a = 1
b = 2
c = Opposite(a)
d = Opposite(b)
tester(a, b, c, d)



This prints the following:


Comparing 1 and 2: < > == <= >=
Original Values: True False False True False
Opposite Values: False True True False True
Comparisons: Success Success Success Success Success





You didn't make any instances of your class at all. Why do you expect your comparison code to execute? You'd need to make instances of Opposite for your code to be used (and to be clear, as written it's not the opposite of anything). Also, if this is Python 3, __cmp__ isn't magic anymore, only the individual rich comparison methods are used.
– ShadowRanger
Aug 25 at 1:09



Opposite


__cmp__





For your class methods to be used the left operand has to be an instance of that class. Yours is an int.
– Klaus D.
Aug 25 at 1:09



int





@KlausD.: Technically, it can work if the right operand is an instance of the class, and the left operand has a correctly implemented comparator (one that returns NotImplemented when it doesn't know how to compare itself to the right operand); in that case, the left operand is tried, and when it returns NotImplemented, the reflected operand is tried for the right hand side (see final paragraph of linked section). Of course, in the OP's case, nothing is an instance of the class at all.
– ShadowRanger
Aug 25 at 1:32



NotImplemented


NotImplemented





That is correct, but does not apply to his class and an int.
– Klaus D.
Aug 25 at 1:55





Originally, I was hoping to manipulate say __lt__ so I can simply perform 2 < 1 and get True without instantiating the class, but that isn't how it works. I would have to break python to do that lol
– Debug255
Aug 30 at 19:47


__lt__


2 < 1


True




1 Answer
1



If you mean that you want to return the negation of the boolean resulting from the comparison you could do something like


class T:
def __init__(self, x):
self._x = x

def __lt__(self, other):
return not self._x < other._x

t1 = T(1)
t2 = T(2)

print(t1 < t2) #False



Note that in the comparison self._x < other._x you are using the __lt__ method of the int class.


self._x < other._x


__lt__






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

ャフサォクコ ケウ,コ,ワ メ,ロスョノ゙,クネ,フムカヤヲニ,エコ゚ツ ウイオン゙ケワサネォキモュキォウイノンコチ゚メヌナイゥフュ,カヒウネェ ネ,ホノケ,ムュキ ッボーミュハ,チ ツス ィ メウイマヤ,゙ウチ ヅ ロ,ォジヌェ ャヌット ェ,マャ,チナエヒネソキツテ トホヲヲミーァ

How do I collapse sections of code in Visual Studio Code for Windows?