8

I would like to assign an another function to len in __init__.py file of my package the following way:

llen = len
len = lambda x: llen(x) - 1

It works fine, but only in the __init__.py file. How can I make it affect other modules in my package?

pppery
  • 3,731
  • 22
  • 33
  • 46
DorianOlympia
  • 841
  • 1
  • 10
  • 22

2 Answers2

4

This may not be the answer you're looking for, but I wouldn't do this if I were you (and I'm pretty sure you can't easily, anyway).

The reason why you shouldn't is that python uses len internally on it's objects to perform certain operations. Another reason is pure broken logic. Your len function defined above would return a negative length for empty lists, or empty things. This seems quite broken to me.

What you can do, is override the length method only on certain classes (this might make a lot of sense for you). For this you can use operator overloading, just override the method __len__ in your class:

class MyList(object):
    def __len__(self,):
        # Do your thing

You may also want to look into meta classes, there is a very good stack overflow question on this subject.

Community
  • 1
  • 1
nichochar
  • 2,720
  • 1
  • 18
  • 16
  • I agree with you! I know such a behaviour is not really appropiate. But this code is a part of my university homework. I have to create a program with really annoying and hard to find bug. I thought assigning something different to an easy and often used function (such as len) is a nice idea! :) – DorianOlympia Nov 01 '15 at 16:41
2

When you try to load a name that is not defined as a module-level global or a function local, Python looks it up in the __builtin__(builtins in Python 3) module. In both versions of Python, this module is also availabe as __builtins__ in the global scope. You can modify this module and this will affect not only your code but any python code anywhere that runs after your code runs!!

import __builtin__ as builtins # import builtins in python 3
llen = len
builtins.len = lambda a:llen(a) - 1
pppery
  • 3,731
  • 22
  • 33
  • 46