Metaclasses in Python
stackoverflow.com
stackoverflow.com
MyClass = MetaClass()
MyObject = MyClass()
Those two code blocks are effectively equivalent: class Quux(type):
#__metaclass__ = type is implicit
pass
class Qux(object):
__metaclass__ = Quux
pass
and: Quux = type('Quux', (type,), {})
Qux = Quux('Qux', (object,), {})
the __metaclass__ attribute merely puts in words what's the callable being called when the keyword class gets parsed and subsequently handled in the current namespace.This class/object unification is one of a bunch of unifications I find extremely satisfying when thinking about how Python ticks.
I'm using Python 2.7.2+ on Debian and I can't get __metaclass__ force upper case attributes inside of a 'module'
Looks like there's a video available at http://ep2011.europython.eu/conference/talks/javascript-for-....
It's something that can be done in Ruby and JavaScript, but I believe it was never allowed in Python in the name of performance (you incur overhead when every number is Fixnum with the same lookup rules as any other instance, for example), and also safety.
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 languages like Javascript and Ruby, Python codebases scale effortlessly and beautifully and without the limitations of "How much freaking online documentation do I need to read to locate the imperative code that's actually running?". While that sort of necessity is the mother of beautiful documentation design you'll find in (and the ascendance of great doc writers among) the Ruby and Javascript communities, I believe its technical risks outweight those tertiary benefits. Extensive and explicit documentation is a necessity that Python does away with entirely, because the code is itself explicit. Python does this at the cost of some convenience and developer happiness. Whereas I give Ruby a 10/10 in the "day-to-day comfort" scale for us dynamic developers, and where Javascript has perhaps a 7/10, I place Python squarely at 9.
By comparison to static high-level languages like Java and ActionScript (and some dynamic languages like Perl and PHP) classical, Python is of course a breeze to write.
As a result of this explicitness, when using a Python framework, you'll rarely need consult documentation or outside advice just to find out what's happening: It's all in the code, and you just have to follow the imports and method calls down the stack.
This modularity also means Pythonists totally avoid collisions in namespacing: whereas the global namespaces of Ruby and Javascript tend to lead to headaches in large codebases, Python is built on the idea of package-as-namespace (directories) and module-as-namespace (.py files)
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 foo = Foo() where
class Foo(object):
pass 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. class Foo(object):
pass
foo = Foo()
foo.name = ...
def hello(self):
...
foo.hello = hello 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)n [8]: class Foo(object): ...: pass ...:
In [9]: blah = Foo()
In [10]: blah.asdf = lambda x: x
In [11]: blah.asdf(3) Out[11]: 3
In [12]: blah.asdf(5) Out[12]: 5
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]: <function hello at 0x103985aa0>
In [26]: goo.hi()
TypeError Traceback (most recent call last)
TypeError: hello() takes exactly 1 argument (0 given) >>> 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()" 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()
<__main__.Foo object at 0x10397f650>