1

I feel this is a very simple question but I can't find to seem a proper answer. Basically I have a list of functions call from a class named simulation:

simulation.addGroup("teapotarmy")
simulation.populateGroup(20)
simulation.addNode("input",INPUT)
simulation.addNode("output",OUTPUT);
simulation.connectNodes("input","output");
simulation.manipOutputNode("output", "group.xvel");
simulation.manipInputNode("input", 1, 0.05);

Is there a way to call those functions without having to repeat the class name everytime? Something along the line of:

(thethingIwant) simulation:
    addGroup("teapotarmy")
    populateGroup(20)
    addNode("input",INPUT)
    ...

I have done this in other programming languages but I haven't figured out the syntax in Python. I have a faint memory of it having something to do with the 'with' statement...? Thanks in advance.

Leon

4

4 回答 4

6

简单地说,没有。没有(很好,请参阅我最后的评论)方法来做到这一点。您可以做的最好的事情是将其分配给另一个更短的名称:

s = simulation
s.addGroup("teapotarmy")
...

这还不错,尽管我认为普通方法是更具可读性的方法。

作为额外的,严格来说你不能这样做并不是真的。您可以以编程方式将所有模拟方法分配给本地命名空间,但是,这将非常令人困惑,我建议不要这样做。

例子:

from contextlib import contextmanager
import inspect

class some_class:
    def test(self):
        print("test!")

@contextmanager
def map_to_local(inst, locals):
    methods = inspect.getmembers(inst, inspect.ismethod)
    for name, method in methods:
        locals[name] = method
    yield
    for name, method in methods:
        del locals[name]

inst = some_class()
with map_to_local(inst, locals()):
    test()

请注意,这非常脆弱 - 您必须小心并执行诸如检查您没有覆盖值、检查在上下文管理器退出之前没有删除值等操作......这也很不清楚发生了什么。

tl; dr:是的,有可能,不,你不应该这样做。您当前的代码很好且清晰。

于 2012-12-02T18:15:07.057 回答
2

要使用当前设计的现有类,通常的解决方案是使用较短的变量名:

s = simulation
s.addGroup("teapotarmy")
s.populateGroup(20)
s.addNode("input",INPUT)
s.addNode("output",OUTPUT)
s.connectNodes("input","output")
s.manipOutputNode("output", "group.xvel")
s.manipInputNode("input", 1, 0.05)

也就是说,另一种解决方案是稍微改变类以使这些方法返回 self。然后你可以写:

(simulation
    .addGroup("teapotarmy")
    .populateGroup(20) 
    .addNode("input",INPUT)
    .addNode("output",OUTPUT)
    .connectNodes("input","output")
    .manipOutputNode("output", "group.xvel")
    .manipInputNode("input", 1, 0.05))

正常的 Python 风格是让变异方法返回None(以提供发生变异的提示);然而,返回self是像你这样的 API 的规范,在这些 API 中,应用一系列转换和状态更新是很常见的。

于 2012-12-02T19:58:27.110 回答
1

我能想到的最接近的事情是利用 Python 的函数也是类的属性(可调用属性)这一事实,因此您可以通过名称“获取”它们并调用它们......

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class Simulation(object):
  def addGroup(self, groupToAdd):
    print "Group to add: %s" % groupToAdd

  def addNode(self, inputType, inputChannel):
    print "My inputs: %s, channel: %s" % (inputType, inputChannel)

if __name__ == "__main__":
  simulation = Simulation()
  functionsToCall = [
      ("addGroup", "teapotarmy"),
      ("addNode", "input", "INPUT"),
    ]
  for functionToCall in functionsToCall:
    getattr(simulation, functionToCall[0])(* functionToCall[1:])

但这可能会使您的代码比以前更加混乱。如果其他人必须修改您的代码,这可能会使他的任务复杂化......相当多。:)

更多信息:Callables包装参数

于 2012-12-02T18:23:41.573 回答
1

对于您在类中定义的每个方法,您都可以返回 self 对象。

class schema:
    def __init__(self,name,age):
        self.name = name 
        self.age = age
    def giveName(self):
        print(self.name)
        return self
    def giveAge(self):
        print(self.age)
        return self

obj = schema(name="yo",age=15)
obj.giveName().giveAge()
于 2020-09-30T03:45:18.603 回答