相关疑难解决方法(0)

实例方法的Python装饰器可以访问该类吗?

嗨我有类似下面的东西.基本上我需要从定义中的实例方法使用的装饰器访问实例方法的类.

def decorator(view):
    # do something that requires view's class
    print view.im_class
    return view

class ModelA(object):
    @decorator
    def a_method(self):
        # do some stuff
        pass
Run Code Online (Sandbox Code Playgroud)

代码原样给出

AttributeError: 'function' object has no attribute 'im_class'

我发现类似的问题/答案 - Python装饰器让函数忘记它属于一个类Python装饰器中的Get类 - 但这些依赖于一种解决方法,它通过抢夺第一个参数在运行时抓取实例.在我的情况下,我将基于从其类中收集的信息调用该方法,因此我不能等待来电.

谢谢.

python decorator

99
推荐指数
6
解决办法
5万
查看次数

获取定义方法的类

如何获得在Python中定义方法的类?

我想要以下示例打印" __main__.FooClass":

class FooClass:
    def foo_method(self):
        print "foo"

class BarClass(FooClass):
    pass

bar = BarClass()
print get_class_that_defined_method(bar.foo_method)
Run Code Online (Sandbox Code Playgroud)

python python-2.6 python-datamodel

77
推荐指数
4
解决办法
4万
查看次数

你如何检查是否绑定了python方法?

给定方法的引用,有没有办法检查方法是否绑定到对象?你还可以访问它绑定的实例吗?

python python-datamodel

33
推荐指数
3
解决办法
9978
查看次数

嘲弄一个班级的建设

我刚刚开始使用Python的模拟库来帮助编写更简洁和隔离的单元测试.我的情况是我有一个类从一个非常多毛的格式读取数据,我想在这个类上测试一个以干净格式呈现数据的方法.

class holds_data(object):
    def __init__(self, path):
        """Pulls complicated data from a file, given by 'path'.

        Stores it in a dictionary. 
        """
        self.data = {}
        with open(path) as f:
            self.data.update(_parse(f))

    def _parse(self, file):
        # Some hairy parsing code here
        pass

    def x_coords(self):
        """The x coordinates from one part of the data
        """
        return [point[0] for point in self.data['points']]
Run Code Online (Sandbox Code Playgroud)

上面的代码简化了我的工作.实际上,这_parse是一个相当重要的方法,我在功能级别上进行了测试.

但是,我希望能够x_coords在单元测试级别进行测试.如果我通过给它一个路径来实例化这个类,它将违反单元测试规则,因为:

在以下情况下,测试不是单元测试:

  • 它涉及文件系统

所以,我希望能够修改__init__方法holds_data,然后只需填写self.data所需的部分x_coords.就像是: …

python unit-testing mocking

11
推荐指数
1
解决办法
9375
查看次数

给定一个方法,如何在Python 3.3中返回它所属的类?

给出x = C.f之后:

class C:
    def f(self):
        pass
Run Code Online (Sandbox Code Playgroud)

我会打电话给谁x回来C

我能做的最好的是exec解析部分x.__qualname__,这是丑陋的:

exec('d = ' + ".".join(x.__qualname__.split('.')[:-1]))
Run Code Online (Sandbox Code Playgroud)

对于一个用例,想象一下我想要一个装饰器来添加super对它应用的任何方法的调用.那个只给出函数对象的装饰器怎么能把类带到super(???下面)?

def ensure_finished(iterator):
    try:
        next(iterator)
    except StopIteration:
        return
    else:
        raise RuntimeError

def derived_generator(method):
    def new_method(self, *args, **kwargs):
        x = method(self, *args, **kwargs)
        y = getattr(super(???, self), method.__name__)\
            (*args, **kwargs)

        for a, b in zip(x, y):
            assert a is None and b is None
            yield

        ensure_finished(x)
        ensure_finished(y)

    return new_method
Run Code Online (Sandbox Code Playgroud)

python metaprogramming python-3.3

7
推荐指数
1
解决办法
817
查看次数

在Python中,你可以调用类A的实例方法,但是传入一个B类的实例吗?

为了重用一些被定义为不同类的实例方法的现有代码,我想要做类似以下的事情:

class Foo(object):
  def __init__(self):
    self.name = "Foo"

  def hello(self):
    print "Hello, I am " + self.name + "."

class Bar(object):
  def __init__(self):
    self.name = "Bar"


bar = Bar()
Foo.hello(bar)
Run Code Online (Sandbox Code Playgroud)

但结果是:

TypeError:必须使用Foo实例作为第一个参数调用未绑定方法hello()(改为使用Bar实例)

这样的事情可能吗?


我应该清楚,我知道这是一个坏主意.显然,真正的解决方案是一些重构.我只是觉得必须有一种方法,事实证明存在.

感谢您的评论.

python oop coding-style

6
推荐指数
2
解决办法
2647
查看次数

获取Python 3中超类的类型

我有一个基类,其中有两个派生自它的类。我希望基类的方法的行为有所不同,具体取决于参数是否与派生类具有相同的类型,或者只是基类的实例但类型不同。这是当前的实现:

class MyBase:
    def __init__(self, foo: int):
        self.foo = foo 

    def __eq__(self, other):
        return self.foo == other.foo 


class MyDerived_1(MyBase):
    def __init__(self, foo: int, bar: int):
        super().__init__(foo)
        self.bar = bar


class MyDerived_2(MyBase):
    def __init__(self, foo: int, bar: int):
        super().__init__(foo)
        self.bar = bar 

    def __eq__(self, other):
        if type(other) == type(self):
            return self.bar == other.bar 
        elif isinstance(other, MyBase):
            return super().__eq__(other)
        else:
            return False
Run Code Online (Sandbox Code Playgroud)

在倒数第四行中,我必须明确引用 MyBase。也许这很好,但我的理解是“super”关键字的一个要点是它应该允许您更改基类,而不必重新编写类中的任何内容。因此,该解决方案的一个潜在问题是,如果 MyBase 发生更改,那么init会很好,因为它调用“super”,但eq不会更新其行为。

所以我尝试用“type(super)”或“type(super())”替换“MyBase”,但这些不引用超类,它们引用对象“super”的类。

请注意,此问题不同于:

获取父类名? 获取Python 3等中未绑定方法对象的定义类。

因为一旦对象被初始化,他们就会寻找父类。

我想我应该能够通过运行 MRO 找到超级类。但这似乎是一个糟糕的解决方案,因为我不是在寻找整个继承树,我只是想知道超类的类型。

有没有办法从“超级”中提取这些信息?

python inheritance super superclass

6
推荐指数
1
解决办法
5732
查看次数

如何在类中使用 FastAPI 创建路由

所以我需要在一个类中有一些路由,但是路由方法需要有selfattr(访问类的属性)。但是,FastAPI 然后假定self是它自己的必需参数并将其作为查询参数放入

这就是我所拥有的:

app = FastAPI()
class Foo:
    def __init__(y: int):
        self.x = y

    @app.get("/somewhere")
    def bar(self): return self.x
Run Code Online (Sandbox Code Playgroud)

但是,422除非您转到 ,否则它将返回/somewhere?self=something。问题在于,那self是 str,因此没用。

我需要一些我仍然可以访问的方法,self而无需将其作为必需的参数。

python class self python-3.x fastapi

6
推荐指数
5
解决办法
5056
查看次数

如何在Python 3.1中的类构造中找到绑定方法的类?

我想写一个装饰器,使类的方法可以被其他方看到; 然而,我所描述的问题与该细节无关.代码看起来大致如下:

def CLASS_WHERE_METHOD_IS_DEFINED( method ):
  ???

def foobar( method ):
  print( CLASS_WHERE_METHOD_IS_DEFINED( method ) )

class X:

  @foobar
  def f( self, x ):
    return x ** 2
Run Code Online (Sandbox Code Playgroud)

我的问题在于装饰foobar()者看到方法的那一刻,它还无法调用; 相反,它可以看到它的未绑定版本.也许这可以通过在类上使用另一个装饰器来解决,该装饰器将处理对绑定方法必须做的任何事情.我将尝试做的下一件事是在装饰方法通过装饰器时简单地使用属性标记,然后使用类装饰器或元类来进行后处理.如果我得到这个工作,那么我不必解决这个谜语,这仍然让我困惑:

任何人都可以在上面的代码中填写有意义的行,CLASS_WHERE_METHOD_IS_DEFINED以便装饰器可以实际打印出f定义的类,它被定义的那一刻?或者在python 3中排除了这种可能性?

python python-3.x

5
推荐指数
1
解决办法
1087
查看次数

用于保存有关类的元数据的装饰器的替代方案

我正在编写一个 GUI 库,我想让程序员提供有关他们程序的元信息,我可以用它来微调 GUI。我打算为此目的使用函数装饰器,例如这样:

class App:
    @Useraction(description='close the program', hotkey='ctrl+q')
    def quit(self):
        sys.exit()
Run Code Online (Sandbox Code Playgroud)

问题是这些信息需要绑定到相应的类。例如,如果该程序是图像编辑器,它可能有一个Image提供更多用户操作的类:

class Image:
    @Useraction(description='invert the colors')
    def invert_colors(self):
        ...
Run Code Online (Sandbox Code Playgroud)

然而,由于未绑定方法的概念已在 python 3 中删除,因此似乎没有办法找到函数的定义类。(我找到了这个旧答案,但这在装饰器中不起作用。)

那么,既然装饰器看起来不起作用,那么最好的方法是什么?我想避免使用类似的代码

class App:
    def quit(self):
        sys.exit()

Useraction(App.quit, description='close the program', hotkey='ctrl+q')
Run Code Online (Sandbox Code Playgroud)

如果可能的话。


为了完整起见,@Useraction装饰器看起来有点像这样:

class_metadata= defaultdict(dict)
def Useraction(**meta):
    def wrap(f):
        cls= get_defining_class(f)
        class_metadata[cls][f]= meta
        return f
    return wrap
Run Code Online (Sandbox Code Playgroud)

python decorator python-3.x

5
推荐指数
1
解决办法
1391
查看次数

为什么在Python 3中可以将实例方法作为类方法调用?

考虑以下课程:

class Foo(object):
    def bar(self):
        print(self)
Run Code Online (Sandbox Code Playgroud)

在Python 2(2.7.13)中,bar()作为类方法调用会引发异常:

>>> Foo.bar('hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got str instance instead)

>>> Foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
Run Code Online (Sandbox Code Playgroud)

bar()作为实例方法调用时,它self在没有参数的情况下被识别为实例

>>> Foo().bar('hello')
Traceback (most recent …
Run Code Online (Sandbox Code Playgroud)

python oop python-3.x

3
推荐指数
1
解决办法
100
查看次数

如何在Python 3.7中重新实现Python的__qualname__?(有一些小的调整)

__qualname__属性对我很有用,因为它使函数具有上下文关系;但是,我很难将其用于我的用例,因为:

  1. __qualname__返回一个字符串。对于我的用例,我需要引用父对象。

  2. __qualname__有时返回super类而不是引用的类。例如:

    class Parent():
    
        def __init__(self):
            pass
    
    
    class Child(Parent):
        pass
    
    
    print(Child.__init__.__qualname__)  # Prints: "Parent.__init__"
    
    Run Code Online (Sandbox Code Playgroud)
  3. 我正在开发的包需要足够强大,据我所知,边缘情况__qualname__没有记录。

除了使用 解析Python 文件之外ast,还可以__qualname__通过检查在Python3 中重新实现吗?Python是如何实现的__qualname__?在重新实现核心功能时,我认为我将能够根据我的用例进行调整。


先前的研究:

我无法在 Python 源代码中找到 qualname 实现。

python introspection python-3.x

3
推荐指数
1
解决办法
735
查看次数