相关疑难解决方法(0)

monkey-patching python一个实例方法

我正在尝试修补类实例,但是我不太清楚如何修补类方法没问题.

>>> class Simple(object): 
...     def make(self, arg):
...         return arg * 2
... 
>>> s = Simple()
>>> def times_four(self, arg):
...   return arg * 4
... 
>>> Simple.make = times_four
>>> s.make(10)
40
Run Code Online (Sandbox Code Playgroud)

但是说我只想make在实例中替换,最简单的方法是什么?

>>> def times_eight(self, arg):
...   return arg * 8
>>> s.make = ???
Run Code Online (Sandbox Code Playgroud)

python

7
推荐指数
3
解决办法
2703
查看次数

python中的猴子补丁绑定方法

>>> class A:
...     def foo(self):
...             print(self)
...
>>>
>>> a = A()
>>> a.foo()
<__main__.A instance at 0x7f4399136cb0>
>>> def foo(self):
...     print(self)
...
>>> a.foo = foo
>>> a.foo()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: foo() takes exactly 1 argument (0 given)
Run Code Online (Sandbox Code Playgroud)

我正在尝试理解 Python 中的猴子补丁。请说明错误的原因以及如何修复它。

python

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

Python中的元编程 - 添加对象方法

我有Python背景(虽然完全是自学成才,所以我可能有一些不良习惯或误解),而我正在努力学习Ruby以扩大我的范围.

我正在阅读一些比较,并看到许多断言"Python不能进行元编程"(或者,更少的是,"Python不能像Meta一样简单地进行元编程").所以我离开后迅速阅读了关于元编程的内容,并且给人的印象是,它基本上是在运行时编辑类/对象的方法/行为(如果我不正确,请纠正我!).

我的印象是,由于Python是动态的,这应该不是问题.但是,我运行了以下测试代码,它没有给出我预期的响应:

>>> class foo:
...     def make_hello_method(self):
...             def hello(obj):
...                     print 'hello'
...             self.hello = hello
...
>>> f = foo()
>>> f.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: foo instance has no attribute 'hello'
>>> f.make_hello_method()
>>> f.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: hello() takes exactly 1 argument (0 given)
Run Code Online (Sandbox Code Playgroud)

我的印象是,对象的每个方法都自动将对象本身作为第一个参数传递(因此将对象方法定义为常量要求(self, [...])).怎么f没有被传递给hello()

python metaprogramming

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

运行时更换方法而不更新私有属性

我了解了如何通过浏览这些链接在Python中运行时替换方法.[ Link1,Link2Link3 ].

当我替换A类的"update_private_variable"方法时,它被替换但不更新私有变量.

import types

class A:
    def __init__(self):
        self.__private_variable = None
        self.public_variable = None

    def update_private_variable(self):
        self.__private_variable = "Updated in A"

    def update_public_variable(self):
        self.public_variable = "Updated in A"

    def get_private_variable(self):
        return self.__private_variable

class B:
    def __init__(self):
        self.__private_variable = None
        self.public_variable = None

    def update_private_variable(self):
        self.__private_variable = "Updated in B"

    def update_public_variable(self):
        self.public_variable = "Updated in B"
Run Code Online (Sandbox Code Playgroud)

在没有替换的情况下调用方法:

a_instance  = A()
a_instance.update_private_variable()
print(a_instance.get_private_variable())
#prints "Updated in A"   
Run Code Online (Sandbox Code Playgroud)

更换后调用方法时:

a_instance  = A()
a_instance.update_private_variable =  types.MethodType(B.update_private_variable, a_instance) …
Run Code Online (Sandbox Code Playgroud)

python python-3.x

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

构造函数(Python)之外的方法中的实例变量 - 为什么以及如何?

我的问题涉及在类构造函数之外的方法中初始化的实例变量.这适用于Python.

我先说出我的理解:

  1. 类可以定义构造函数,也可以定义其他方法.
  2. 实例变量通常在构造函数中定义/初始化.
  3. 但是实例变量也可以在构造函数之外定义/初始化,例如在同一类的其他方法中.
  4. (2)和(3)的一个例子 - 参见下面的Cat类中的self.meowself.roar:

    class Cat():
    
        def __init__(self):
            self.meow = "Meow!"
        def meow_bigger(self):
            self.roar = "Roar!"
    
    Run Code Online (Sandbox Code Playgroud)

我的问题:

  1. 为什么在构造函数中初始化实例变量是最佳实践?

  2. 如果实例变量在构造函数以外的方法中定期初始化,可能会出现一般/特定的混乱?(例如,在他的编程Python中读过Mark Lutz的Tkinter指南,我认为这很好,我注意到用于保存PhotoImage对象/引用的实例变量在其他方法中初始化,而不是在构造函数中初始化.它似乎没有工作问题,但从长远来看,这种做法是否会引起问题?)

  3. 在哪些情况下,在其他方法中而不是在构造函数中初始化实例变量会更好


  1. 据我所知,实例变量不是在创建类对象时存在,而是实例化类对象之后存在.继续我上面的代码,我证明了这一点:

    >> c = Cat() 
    >> c.meow
    'Meow!'
    >> c.roar
    Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
    AttributeError: 'Cat' object has no attribute 'roar'
    >>> c.meow_bigger()
    >>> c.roar
    'Roar!'
    
    Run Code Online (Sandbox Code Playgroud)

    原样:

    • 我一开始无法访问实例变量(c.roar).
    • 但是,在我调用实例方法c.meow_bigger()一次后,我突然能够访问实例变量c.roar …

python constructor class instance-variables

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

向现有对象实例添加属性

我想创建一个具有某些属性的对象。我想动态添加它们。与向现有对象实例添加方法类似,但使用属性而不是方法。下面是一个简单的例子。

我喜欢动态创建:

class A():
    @property
    def a(self):
        return self._a
    @a.setter
    def a(self, x):
        self._a = 10*x

    @property
    def b(self):
        return self._b
    @b.setter
    def b(self, x):
        self._b = 10*x
Run Code Online (Sandbox Code Playgroud)

要使用方法来做到这一点,我会这样做:

class B():
    def __init__(self):
        for i in range(70,80):
            self.__dict__[chr(i)] = types.MethodType(lambda self,x: x*i, self)
Run Code Online (Sandbox Code Playgroud)

对于我尝试过的属性:

class B():
    def __init__(self):
        for i in range(70,80):
            def tmp(self, x):
                self._x = i*x
            self.__dict__[chr(i)] = property(fget=lambda self: self._i, fset=tmp)
Run Code Online (Sandbox Code Playgroud)

我也找到了types.DynamicClassAttribute,但我不确定这是否有帮助。

这里提出了一个相关问题,关于向类添加属性(在 python 2 中): Dynamically add @property in python。我不知道如何将其扩展到类的实例。

背景 …

python

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

将新方法添加到Python Swig Template类

我需要在swig模板类中添加一个新方法,例如:

我在myswig.i中声明了一个模板类,如下所示:

%template(DoubleVector) vector<double>;
Run Code Online (Sandbox Code Playgroud)

这将在生成的.py文件中生成一个名为"DoubleVector"的类,其中包含一些生成的方法.假设它们是func1(),func2()和func3().这些是生成的函数,我无法控制它们.现在,如果我想向这个类(DoubleVector)添加一个名为"func4()"的新方法,我该怎么办呢?可能吗?

我知道一个名为%pythoncode的标识符,但我不能用它来定义这个模板类中的新函数.

python swig templates

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

Django:如何在单元测试中隐藏 Traceback 以提高可读性?

我发现为一个简单的失败的单元测试获取如此多的细节有点令人恼火。除了实际定义的断言消息之外,是否可以抑制所有内容?

Creating test database for alias 'default'...
.F
======================================================================
FAIL: test_get_sales_item_for_company (my_app.tests.SalesItemModelTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/kave/projects/my/my_app/tests.py", line 61, in test_get_sales_item_for_company
    self.assertEqual(sales_items.count(), 1, 'Expected one sales item for this company, but got %s' % sales_items.count())
AssertionError: Expected one sales item for this company, but got 2

----------------------------------------------------------------------
Ran 2 tests in 0.313s

FAILED (failures=1)
Destroying test database for alias 'default'...
Run Code Online (Sandbox Code Playgroud)

我觉得这有点不必要。我需要知道失败的测试名称(方法)和断言消息。真的不需要回溯..

Traceback (most recent call last):
  File "/home/kave/projects/my/my_app/tests.py", line 61, in test_get_sales_item_for_company
    self.assertEqual(sales_items.count(), 1, 'Expected one sales …
Run Code Online (Sandbox Code Playgroud)

django unit-testing

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

不同类型的类变量之间有什么区别?

首先,有A两个类变量和两个实例变量的类:

In [1]: def fun(x, y): return x + y

In [2]: class A:
   ...:     cvar = 1
   ...:     cfun = fun
   ...:     def __init__(self):
   ...:         self.ivar = 100
   ...:         self.ifun = fun
Run Code Online (Sandbox Code Playgroud)

我们可以看到int类的类变量和实例变量都可以正常工作:

In [3]: a = A()

In [4]: a.ivar, a.cvar
Out[4]: (100, 1)
Run Code Online (Sandbox Code Playgroud)

但是,如果检查函数类型变量,情况就会改变:

In [5]: a.ifun, a.cfun
Out[5]: 
(<function __main__.fun>,
 <bound method A.fun of <__main__.A instance at 0x25f90e0>>)

In [6]: a.ifun(1,2)
Out[6]: 3

In [7]: a.cfun(1,2)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/home/future/<ipython-input-7-39aa8db2389e> …
Run Code Online (Sandbox Code Playgroud)

python variables class instance

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

如何在python中向描述符或属性添加方法

我正在尝试编写一个可以轻松扩展的模拟类。为此,我想使用类似于属性的东西,但这也提供了update一种可以针对不同用例以不同方式实现的方法:

class Quantity(object):
    
    def __init__(self, initval=None):
        self.value = initval

    def __get__(self, instance, owner):
        return self.value

    def __set__(self, instance, value):
        self.value = value
    
    def update(self, parent):
        """here the quantity should be updated using also values from
        MySimulation, e.g. adding `MySimulation.increment`, but I don't
        know how to link to the parent simulation."""

        
class MySimulation(object):
    "this default simulation has only density"
    density = Quantity()
    increment = 1
    
    def __init__(self, value):
        self.density = value
    
    def update(self):
        """this one does not work because …
Run Code Online (Sandbox Code Playgroud)

python oop python-descriptors

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