【问题标题】:Python - return default method on class initializationPython - 在类初始化时返回默认方法
【发布时间】:2021-07-28 00:01:34
【问题描述】:

我正在重构代码,想知道这是否可能。

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]))

返回

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

我想要:

4
4

努力尝试,我读到了metaclass__new__,但不知道该怎么做。

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>

它不起作用,它有 50% 的功能。

很遗憾,我现在没有时间,但以我今天的知识,不可能用元类来做到这一点。在 sqlite3 中我们可以使用 cur.execute("SQL;"), cur.execute("SQL;").fetchone() 所以可以做到。

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

我想知道它是否可以比我的解决方案做得更好或更智能,因为在我看来,使用函数返回类是一种 hack。

研究了这段代码,它不可能知道何时替换返回的对象,我将把它重新输入到没有函数的类。刚刚检查了一个班级的同样问题。将参数从方法传递到元类时遇到问题。

【问题讨论】:

  • 答案在答案部分,而不是在问题中,即使您是在回答自己的问题。另外,your answer doesn't work.
  • 我看到了问题,我需要重新考虑它。谢谢。

标签: python python-3.x class methods


【解决方案1】:

这就是我正在做的事情

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____iter__ 是这个问题之王的解决方案。

【讨论】:

    【解决方案2】:

    您可以简单地为您的班级定义__repr__ 并使其返回列表的长度作为字符串

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

    例子:

    >>> print(a([1,2,3,4]))
    4
    

    【讨论】:

    • 这只有在您只关心打印时才有效。
    • @user2357112supportsMonica,是的,绝对是。我不认为 OP 实际上想要将他们的列表转换为整数......尤其是在类的初始化期间
    • 我会接受这个答案,因为它让我找到了正确的解决方案,并且更接近原始问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-14
    • 2022-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多