在Python 3.0中动态向类添加方法

2024-01-27

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

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

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

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

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

outputs:

{'__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参数(条件设置器在运行时动态添加,但添加到类中,而不是单独添加到每个实例中)。如果Search 具有不同条件设置器的对象需要创建,那么上述方法的以下变体就可以工作(__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 http://docs.python.org/howto/descriptor.html#functions-and-methods


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

       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>

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在Python 3.0中动态向类添加方法 的相关文章

随机推荐

  • 如何以本地用户身份(无管理员权限)在 Windows 上安装 NodeJS LTS

    我以简单用户身份使用 Windows 我没有任何管理员权限 并且想要安装 NodeJS LTS On the 下载站点 https nodejs org en download 我可以选择仅下载二进制文件node exe 其中不包括npm
  • 打开文件的命令按钮 - 位于同一单元格按钮中的文件路径对齐到

    我正在尝试获取一个可以分配给命令按钮的宏 我有多个按钮可以打开不同的文件 因此在每个单元格中我都包含不同的文件路径 目前 我的命令按钮正在寻找特定的单元格引用并打开该值 有什么方法可以让宏在与其对齐的单元格中查找值 我目前正在使用两个宏 一
  • 没有这样的目的地

    我在我的网站中使用 Stripe 方法 用户从我的网站购买产品并通过 stripe 完成付款 我想收取佣金并将剩余的钱发送给服务提供商 当我尝试在条纹中使用传输方法时 它会显示错误消息 message No such destination
  • 如何使用 jq 获取两个 JSON 数组的交集

    给定数组 X 和 Y 最好都作为输入 但否则 一个作为输入 另一个硬编码 如何使用 jq 输出包含两者共有的所有元素的数组 例如f 的值是多少 使得 echo 1 2 3 4 jq f 2 4 6 8 10 会输出 2 4 我尝试过以下方法
  • 你能在 jQuery 中扩展 val() 函数吗?

    有没有办法扩展 jQuery 中的 val 函数 基本上 我想要做的是如果有内容被动态输入到输入中 则设置一个类变量 通常会是这样的 var thisVal Hello World myInput val thisVal addClass
  • Javascript parseFloat 和 null

    我对 javascript 非常陌生 因为我目前正在 jQuery Mobile 中制作跨平台 Web 应用程序 我已经使用了 XML 解析到 HighCharts 图表的示例 但是当我在系列数据中遇到 null 时 它无法绘制任何线条并使
  • 颜色逐渐变化

    屏幕左上角的标志如何随着鼠标滑过而逐渐改变颜色 我认为它是用 jquery 完成的 如果您不知道代码 您能给我指点可以的教程吗 谢谢 http www shopdev co uk blog http www shopdev co uk bl
  • 即使进行所有优化,Android 模拟器也会出现延迟

    HAXM 启用版本 7 1 0 我验证了它在模拟器运行时正常工作 模拟器使用 Nvidia GPU 但在任何给定时间它仅使用最多 7 的 GPU 我有 27 3 1 的模拟器版本 最新 尝试过 x86 图像和 x86 x64 图像 我尝试过
  • 多个按钮上的 javascript 函数

    我有三个按钮 我希望它们在按下时改变颜色 并在再次按下时恢复为无颜色 我在 stackoverflow 上找到了这段代码 它几乎可以让我做到这一点 但是它只适用于一个按钮 其他两个不受影响 另外 当我按下另外两个按钮中的一个时 第一个按钮会
  • 如何在 mongodb 中更新多个数组元素

    我有一个 Mongo 文档 其中包含一个元素数组 我想重置 handled数组中所有对象的属性 其中 profile XX 该文件的形式如下 id ObjectId 4d2d8deff4e6c1d71fc29a07 user id 7146
  • 发帖后查看未更新

    我有一个控制器方法 CreateOrUpdate 该方法应该将汽车保存到数据库 然后正常返回 public ActionResult CreateOrUpdate int ID 0 Car car new Car ID HttpPost p
  • 如何测试 JSONObject 是否为空或不存在

    我有一套JSONObject我从服务器接收并操作的值 大多数时候我得到一个JSONObject带有一个值 比如说统计数据 有时 它返回一个Error带有代码和错误描述的对象 如何构建我的代码 使其在返回错误时不会中断 我以为我可以做到这一点
  • 非规范化是为了理智还是为了性能?

    我开始了一个新项目 他们有一个非常标准化的数据库 所有可以查找的内容都存储为查找表的外键 这是规范化的并且很好 但我最终为最简单的查询执行了 5 个表连接 from va in VehicleActions join vat in Vehi
  • 未找到 Laravel Passport 安装类

    我正在尝试配置我的 Laravel 应用程序以使用 Passport 但在加载 AppServiceProvider php 中的类时遇到了困难 这是我所做的
  • 为什么我的 MFC 应用程序在与两个滚动条交互后挂起?

    我正在开发一个 MFC 应用程序 在 Win10 下运行 其中包含一个图形 CAD 样式编辑器窗口 编辑器窗口包含用户可以重新定位和配置的图标 在包含许多元素的布局中 我们发现编辑器窗口可能会挂起长达 30 秒 这个问题是not当我们的大多
  • 使用 AngularJS 排除 url 中的路径

    我的角度应用程序有多个用户可以访问的页面 我想隐藏所有其他网址并仅向用户显示基本网址 因此 假设我的基本网址是 www example com 并且我还有其他页面 例如 关于 联系我们 等 目前 当用户单击 关于 时 网址将更改为 www
  • 本地通知

    本地通知可以在模拟器上运行吗 如果我关闭 而不是最小化 程序 本地通知会运行吗 是的 也是的 看 http iphonesdkdev blogspot com 2010 04 local push notification sample c
  • DataGrid 列标题与数据不对齐

    我有一个 DataGrid 就 DataGrid 而言它非常简单 由于某种原因 标题与其余数据不对齐 如下面的屏幕截图所示 我已经在互联网上搜索过 但似乎找不到解决方案 这是我的数据网格代码 Grid gt
  • 如何在不编译的情况下安装wkhtmltopdf补丁qt?

    我正在使用 google 云实例作为主机 Odoo somo 报告打印为 pdf 正常 但其他使用自定义纸张格式的会出现以下错误 开关 header spacing 不支持使用未打补丁的 qt 将被忽略 开关 header html 不支持
  • 在Python 3.0中动态向类添加方法

    我正在尝试用 Python 编写一个数据库抽象层 它允许您使用链式函数调用构建 SQL 语句 例如 results db search book author J K Rowling price lt 40 00 title Harry e