Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using properties on an old-style python class cause problems

Pretty simple question. I've seen it mentioned in many places that using properties on an old-style class shouldn't work, but apparently Qt classes (through PyQt4) aren't new-style and there are properties on a few of them in the code I'm working with (and as far as I know the code isn't showing any sorts of problems)

I did run across a pyqtProperty function, but I can't seem to find any documentation about it. Would it be a good alternative in this instance?

like image 462
Cole Anagnost Avatar asked Aug 04 '09 23:08

Cole Anagnost


People also ask

Should you use properties in Python?

Python's property() is the Pythonic way to avoid formal getter and setter methods in your code. This function allows you to turn class attributes into properties or managed attributes. Since property() is a built-in function, you can use it without importing anything.

What does @property mean in Python?

The @property is a built-in decorator for the property() function in Python. It is used to give "special" functionality to certain methods to make them act as getters, setters, or deleters when we define properties in a class.

What is property in Python class?

In Python, property() is a built-in function that creates and returns a property object. The syntax of this function is: property(fget=None, fset=None, fdel=None, doc=None)

How do Python properties work?

The property() method in Python provides an interface to instance attributes. It encapsulates instance attributes and provides a property, same as Java and C#. The property() method takes the get, set and delete methods as arguments and returns an object of the property class.


1 Answers

property works because QObject has a metaclass that takes care of them. Witness this small variation on @quark's code...:

from PyQt4.QtCore import QObject

def makec(base):
  class X( base ):
      def __init__(self):
          self.__x = 10
      def get_x(self):
          print 'getting',
          return self.__x
      def set_x(self, x):
          print 'setting', x
          self.__x = x
      x = property(get_x, set_x)

  print 'made class of mcl', type(X), issubclass(type(X), type)
  return X

class old: pass
for base in (QObject, old):
  X = makec(base)
  x = X()
  print x.x # Should be 10
  x.x = 30
  print x.x # Should be 30

running this emits:

made class of mcl <type 'PyQt4.QtCore.pyqtWrapperType'> True
getting 10
setting 30
getting 30
made class of mcl <type 'classobj'> False
getting 10
30

see the difference? In the class that's really a legacy (old-type) class, the one made the second time, metaclass is classobj (which ISN'T a subclass of type) and properties don't work right (assigning x.x bypasses the property, and after that getting x.x doesn't see the property any more either). But in the first case, the Qt case, there's a different metaclass, and it IS a subclass of type (so it's not really correct to say the class "isn't new-style"!), and things therefore DO work correctly.

like image 59
Alex Martelli Avatar answered Oct 16 '22 01:10

Alex Martelli