Live data from Hacker News

Metaclasses in Python

stackoverflow.com

21–30 of 32 posts

Re: Metaclasses in Python

#21
post #16
post #14

Earlier quoted context omitted.

In javascript you can modify an object var foo = Object(); foo.blah = function(x,y) { ... }; But in python, that doesn't quite work. You can only do foo = object() foo.blah = lambda x,y: ... lambdas are a bit more limited as they are restricted to one line, and you can't have print statements, which makes complicated expressions rather ugly. edit: ah, as someone noted, the second code snippet should be something like…

That's not quite right. While you're correct that lambda statements are restricted, I have never actually seen a lambda expression used to extend an object. Instead, you use a named function, which has none of these restrictions: foo = object() foo.name = "Hi thar" def hello(self): print "Hello, I'm %s" % self.name foo.hello = hello This is, in fact, one of the reasons why the self parameter is explicit.

Also, i forgot to add, your code snippet doesn't work. Some magic goes into the self binding.

    In [21]: def hello(self):
    ....:    print self.name
    ....: 
    In [22]: class Foo(object):
    ....:     name = 'blah'
    ....: 
    In [23]: goo = Foo()
    go
    In [24]: goo.hi = hello
    In [25]: goo.hi
    Out[25]: 
    In [26]: goo.hi()
    TypeError                                 Traceback (most     recent call last)

    TypeError: hello() takes exactly 1 argument (0 given)

Re: Metaclasses in Python

#22
post #21
post #16

Earlier quoted context omitted.

That's not quite right. While you're correct that lambda statements are restricted, I have never actually seen a lambda expression used to extend an object. Instead, you use a named function, which has none of these restrictions: foo = object() foo.name = "Hi thar" def hello(self): print "Hello, I'm %s" % self.name foo.hello = hello This is, in fact, one of the reasons why the self parameter is explicit.

Also, i forgot to add, your code snippet doesn't work. Some magic goes into the self binding. In [21]: def hello(self): ....: print self.name ....: In [22]: class Foo(object): ....: name = 'blah' ....: In [23]: goo = Foo() go In [24]: goo.hi = hello In [25]: goo.hi Out[25]: In [26]: goo.hi() TypeError Traceback (most recent call last) TypeError: hello() takes exactly 1 argument (0 given)

Use types.MethodType for that:

    >>> import types
    >>> 
    >>> def hello(self):
    ...     print self.name
    ... 
    >>> class Foo(object):
    ...     name = 'blah'
    ... 
    >>> goo = Foo()
    >>> goo.hi = types.MethodType(hello, Foo)
    >>> 
    >>> goo.hi()
    blah
Edit: pre-2.6 you'd use "new.instancemethod()"

Re: Metaclasses in Python

#24
post #21

Earlier quoted context omitted.

Also, i forgot to add, your code snippet doesn't work. Some magic goes into the self binding. In [21]: def hello(self): ....: print self.name ....: In [22]: class Foo(object): ....: name = 'blah' ....: In [23]: goo = Foo() go In [24]: goo.hi = hello In [25]: goo.hi Out[25]: In [26]: goo.hi() TypeError Traceback (most recent call last) TypeError: hello() takes exactly 1 argument (0 given)

Use types.MethodType for that: >>> import types >>> >>> def hello(self): ... print self.name ... >>> class Foo(object): ... name = 'blah' ... >>> goo = Foo() >>> goo.hi = types.MethodType(hello, Foo) >>> >>> goo.hi() blah Edit: pre-2.6 you'd use "new.instancemethod()"

Yes, or alternatively I believe

    In [27]: class Foo(object):
    ....:     pass
    ....: 
 
    In [28]: def hello(self):
    ....:     print self
    ....: 

    In [29]: blah = Foo()

    In [30]: blah.hello = hello.__get__(blah, Foo) 

    In [31]: blah.hello()
    

Re: Metaclasses in Python

#28
post #7

Earlier quoted context omitted.

Well in JS you could do String.prototype.fnName = function(){}; to add fnName as a method to all strings even if they are already instantiated, is that possible with Python?

No. In Python, primitives prototypes aren't mutable. Pythonic code is meant to be modular, which leads to extreme explicitness. For example, while `string_utils.capitalize(my_string)` is a bit more longwinded than `my_string.capitalize()` in JS or even `my_string.capitalize` in Ruby, this minor bit of ongoing typing overhead will yield a beautifully explicit codebase over time. By comparison to other dynamic language…

Great reply, thanks.

Re: Metaclasses in Python

#29
post #16

Earlier quoted context omitted.

That's not quite right. While you're correct that lambda statements are restricted, I have never actually seen a lambda expression used to extend an object. Instead, you use a named function, which has none of these restrictions: foo = object() foo.name = "Hi thar" def hello(self): print "Hello, I'm %s" % self.name foo.hello = hello This is, in fact, one of the reasons why the self parameter is explicit.

The above doesn't really work as the builtin object class doesn't allow extra attributes. Still any pure Python class does by default: class Foo(object): pass foo = Foo() foo.name = ... def hello(self): ... foo.hello = hello

You should either remove `self` or bind it differently:

  foo = Foo()
  def hello():
      print("hello, %s" % (foo,))
  foo.hello = hello
`foo` is an instance therefore `self == foo` already.

  def hello(self):
      print("hello, %s" % (self,))
  foo.hello = types.MethodType(hello, foo)

Re: Metaclasses in Python

#30
If I'm not mistaken the authors of Smalltalk realized that metaclasses were a mistake long before they appeared in Python. Yet they were added to Python anyway.
Post reply on HN