0

I'm refactoring code and wonder if this is possible.

def a(array):
    class MyClass(object):
        def length():
            return len(array)
    return MyClass
                                                                               
print(a([1,2,3,4]).length())                                                      
print(a([1,2,3,4]))

It returns

4
<class '__main__.a.<locals>.MyClass'>

and i want:

4
4

Trying hard, i read about metaclass and __new__ but cant figure out how to do it.

or

class a():          
    def __init__(self, array):
        self.array = array
    def length(self):
        return len(self.array)

print(a([1,2,3,4]).length()) #   4                                                  
print(a([1,2,3,4]))          #   <__main__.a object at 0x7fab704c9e50>

It's not working, it has 50% functionality.

So sad i don't have time right now but with my today's knowledge its impossible to do it with metaclass. In sqlite3 we can use cur.execute("SQL;"), cur.execute("SQL;").fetchone() so it is possible to do it.

class Metaclass(type):
    def __new__(metacls, name, bases, attrs):                                                                     
        try:                                                                   
            return attrs['length']()                                                                                                                                              
        except KeyError:                                                                          
            pass                                                               

        return type.__new__(metacls, name, bases, attrs)

def a(array):
    class MyClass(metaclass=Metaclass):
        def length():
            return len(array)
    return MyClass

print(a([1,2,3,4]).length()) #   <-  This is not working.                                                 
print(a([1,2,3,4]))          #   4

I would like to hear if it could be done better or smarter tham my solution, because using function returning class it's a hack in my opinion.

Studied this code and its impossible to know when to replace returning object, i will retype this to class without function. Just checked same problem with just single class. Had trouble with passing arguments from method to metaclass.

2
  • 1
    Answers go in the answer section, not in the question, even if you're answering your own question. Also, your answer doesn't work. Commented May 5, 2021 at 16:23
  • I see the problem, i need to rethink it. Thanks. Commented May 5, 2021 at 16:32

2 Answers 2

2

You can simply define __repr__ for your class and make it return the length of the list as a string:

class a():          
    def __init__(self, array):
        self.array = array
    def length(self):
        return len(self.array)

    def __repr__(self):
        return str(self.length())

Example:

>>> print(a([1,2,3,4]))
4
Sign up to request clarification or add additional context in comments.

3 Comments

This only works if all you care about is printing, though.
@user2357112supportsMonica, yes, most definitely. I don't think OP actually wants to convert their list to an integer... especially during the initialization of the class
I will accept this answer because it allowed me to find the right solution, and its more close to the original question.
0

This is what i was doing

import sqlite3                                                                                                   
import contextlib                                                                                                
class cur_execute():                                                                                            
    def __init__(self, sql, data=[]):                                                                            
        self.sql = sql                                                                                           
        self.data = data                                                                                         
                                                                                                             
    def fetchall(self):                                                                                          
        with sqlite3.connect('/opt/portal/db/portal.sqlite3') as con:                                            
            con.execute('pragma journal_mode=wal;')                                                              
            con.row_factory = sqlite3.Row                                                                        
            with contextlib.closing(con.cursor()) as c:                                                          
                for row in c.execute(self.sql, self.data):                                                       
                    yield row                                                                                    
                                                                                                             
    def __iter__(self):                                                                                          
        yield from self.fetchall()                                                                               
                                                                                                             
for row in cur_execute("SELECT * FROM ITEMS;").fetchall():                                                      
    print(str(row))                                                                                              
for row in cur_execute("SELECT * FROM ITEMS;"):                                                                 
    print(str(row))

__repr__ and __iter__ are solution for this king of problems.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.