gpt4 book ai didi

python-3.x - 在 Python 3.0 中为类动态添加方法

转载 作者:太空狗 更新时间:2023-10-29 20:11:36 24 4
gpt4 key购买 nike

我正在尝试用 Python 编写一个数据库抽象层,它允许您使用链式函数调用构造 SQL 语句,例如:

results = db.search("book")
.author("J. K. Rowling")
.price("<40.00")
.title("Harry")
.execute()

但是当我尝试将所需的方法动态添加到 db 类时遇到了问题。

这是我的代码的重要部分:

import inspect

def myName():
return inspect.stack()[1][3]

class Search():

def __init__(self, family):
self.family = family
self.options = ['price', 'name', 'author', 'genre']
#self.options is generated based on family, but this is an example
for opt in self.options:
self.__dict__[opt] = self.__Set__
self.conditions = {}

def __Set__(self, value):
self.conditions[myName()] = value
return self

def execute(self):
return self.conditions

但是,当我运行示例时,例如:

print(db.search("book").price(">4.00").execute())

输出:

{'__Set__': 'harry'}

我是不是用错了方法?有没有更好的方法来获取被调用函数的名称或以某种方式制作函数的“硬拷贝”?

最佳答案

您可以简单地添加搜索功能(方法)在类创建之后:

class Search:  # The class does not include the search methods, at first
def __init__(self):
self.conditions = {}

def make_set_condition(option): # Factory function that generates a "condition setter" for "option"
def set_cond(self, value):
self.conditions[option] = value
return self
return set_cond

for option in ('price', 'name'): # The class is extended with additional condition setters
setattr(Search, option, make_set_condition(option))

Search().name("Nice name").price('$3').conditions # Example
{'price': '$3', 'name': 'Nice name'}

PS: 这个类有一个 __init__() 方法没有 family 参数(条件 setter 是在运行时动态添加的,但被添加到类中,而不是分别添加到每个实例中)。如果需要创建Search 具有不同条件 setter 的对象,则上述方法的以下变体有效(__init__() 方法有一个family 参数):

import types

class Search: # The class does not include the search methods, at first

def __init__(self, family):
self.conditions = {}
for option in family: # The class is extended with additional condition setters
# The new 'option' attributes must be methods, not regular functions:
setattr(self, option, types.MethodType(make_set_condition(option), self))

def make_set_condition(option): # Factory function that generates a "condition setter" for "option"
def set_cond(self, value):
self.conditions[option] = value
return self
return set_cond

>>> o0 = Search(('price', 'name')) # Example
>>> o0.name("Nice name").price('$3').conditions
{'price': '$3', 'name': 'Nice name'}
>>> dir(o0) # Each Search object has its own condition setters (here: name and price)
['__doc__', '__init__', '__module__', 'conditions', 'name', 'price']

>>> o1 = Search(('director', 'style'))
>>> o1.director("Louis L").conditions # New method name
{'director': 'Louis L'}
>>> dir(o1) # Each Search object has its own condition setters (here: director and style)
['__doc__', '__init__', '__module__', 'conditions', 'director', 'style']

引用:http://docs.python.org/howto/descriptor.html#functions-and-methods


如果您确实需要知道存储它们的属性名称的搜索方法,您可以简单地在 make_set_condition() 中设置它

       set_cond.__name__ = option  # Sets the function name

(就在 return set_cond 之前)。执行此操作之前,方法 Search.name 具有以下名称:

>>> Search.price
<function set_cond at 0x107f832f8>

在设置了它的__name__ 属性之后,你会得到一个不同的名字:

>>> Search.price
<function price at 0x107f83490>

以这种方式设置方法名称可以使涉及该方法的可能错误消息更容易理解。

关于python-3.x - 在 Python 3.0 中为类动态添加方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8276733/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com