As already indicated, class attributes (assigned at class level) and instance attributes (assigned as a self attribute for example in __init__) are different.
On the other hand, in your first class you are defining two different attributes (class x and instance x) that coexist, but that can interfere with each other. The code below try to show the problems you can get if you define the class that way.
In [32]: class main():
....: x = 1
....: def disp(self):
....: print(self.x)
....:
# I create 2 instances
In [33]: jim = main()
In [34]: jane = main()
# as expected...:
In [35]: main.x
Out[35]: 1
In [36]: jim.x
Out[36]: 1
In [37]: jane.x
Out[37]: 1
# now, I assign to jim attribute x
In [38]: jim.x = 5
# main class preserves its attribute value as well as jane instance
In [39]: main.x
Out[39]: 1
In [40]: jane.x
Out[40]: 1
# But what happens if I change the class attribute ?
In [41]: main.x = 10
# nothing to jim (I overwrote before jim.x)
In [42]: jim.x
Out[42]: 5
# but jane did see the change
In [43]: jane.x
Out[43]: 10