Python allows multiple ways of doing OO. It's just that there's a default way that's preferable, so pretty much noone needs to roll their own variant, although the techniques get used elsewhere. You'll see the same thing with Perl 6 (see Apocalypse 12, etc) -- the default OO style will be good enough that only a handful of powerusers (and perhaps some dinosaurs ;-) will want/need anything different.
Large quantities of Python code hidden by readmore tag for the benefit of the uninterested:
# The One Obvious Way To Do It
class make_obj(object):
def __init__(self, x):
self.x = x
def f(self, a):
return self.x * a
obj1 = make_obj(2)
obj2 = make_obj(2)
print obj1.f(2), obj2.f(2)
obj1.x = 3
print obj1.f(2), obj2.f(2)
print "---"
def f(self, a):
return self["x"] * a
def make_obj(x):
self = {"x": x}
return self
obj1 = make_obj(2)
obj2 = make_obj(2)
print f(obj1, 2), f(obj2, 2)
obj1["x"] = 3
print f(obj1, 2), f(obj2, 2)
print "---"
def make_obj(x):
def self():
self.x = x
def f(a):
return self.x*a
self.f = f
self()
return self
obj1 = make_obj(2)
obj2 = make_obj(2)
print obj1.f(2), obj2.f(2)
obj1.x = 3
print obj1.f(2), obj2.f(2)
print "---"
class make_obj(object):
def __init__(self, x):
self._x = x
def f(self, a):
return self._x*a
def get_x(self):
return self._x
def set_x(self, x):
self._x = x
x = property(get_x, set_x)
obj1 = make_obj(2)
obj2 = make_obj(2)
print obj1.f(2), obj2.f(2)
obj1.x = 3 # or obj1.set_x(3) if you really feel Java-ish
print obj1.f(2), obj2.f(2)
print "---"
class make_obj(object): pass
def init(obj, x):
def f(a):
return obj.x * a
obj.x = x
obj.f = f
obj1 = make_obj()
init(obj1, 2)
obj2 = make_obj()
init(obj2, 2)
print obj1.f(2), obj2.f(2)
obj1.x = 3
print obj1.f(2), obj2.f(2)
print "---"
class make_obj(object):
def __getattribute__(self, name):
if name == "f":
def f(a):
return self.x * a
return f
elif name == "x":
return object.__getattribute__(self, "x")
def __setattr__(self, name, val):
if name == "x":
object.__setattr__(self, name, val)
obj1 = make_obj()
obj2 = make_obj()
obj1.x = 2
obj2.x = 2
print obj1.f(2), obj2.f(2)
obj1.x = 3
print obj1.f(2), obj2.f(2)
print "---"
class make_obj(object):
def __new__(typ, *args, **kwargs):
self = object.__new__(typ)
self.x = args[0]
def f(a):
return self.x * a
self.f = f
return self
obj1 = make_obj(2)
obj2 = make_obj(2)
print obj1.f(2), obj2.f(2)
obj1.x = 3
print obj1.f(2), obj2.f(2)
print "---"