相关疑难解决方法(0)

理解__get__和__set__以及Python描述符

试图了解Python的描述符是什么以及它们对什么有用.但是,我没有成功.我理解它们是如何工作的,但这是我的疑惑.请考虑以下代码:

class Celsius(object):
    def __init__(self, value=0.0):
        self.value = float(value)
    def __get__(self, instance, owner):
        return self.value
    def __set__(self, instance, value):
        self.value = float(value)


class Temperature(object):
    celsius = Celsius()
Run Code Online (Sandbox Code Playgroud)
  1. 为什么我需要描述符类?请使用此示例或您认为更好的示例进行说明.

  2. 什么是instanceowner这里?(in __get__).所以我的问题是,第三个参数的目的是什么?

  3. 我该怎么称呼/使用这个例子?

python descriptor

287
推荐指数
5
解决办法
10万
查看次数

Python:在运行时更改方法和属性

我希望在Python中创建一个可以添加和删除属性和方法的类.我该怎么做呢?

哦,请不要问为什么.

python reflection runtime

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

如何在python中为类动态创建类方法

如果我定义一个小python程序

class a():
    def _func(self):
        return "asdf"

    # Not sure what to resplace __init__ with so that a.func will return asdf
    def __init__(self, *args, **kwargs):
         setattr(self, 'func', classmethod(self._func))

if __name__ == "__main__":
    a.func
Run Code Online (Sandbox Code Playgroud)

我收到回溯错误

Traceback (most recent call last):
  File "setattr_static.py", line 9, in <module>
    a.func
AttributeError: class a has no attribute 'func'
Run Code Online (Sandbox Code Playgroud)

我想弄清楚的是,如何在不实例化对象的情况下动态地将类方法设置为类?


编辑:

这个问题的答案是

class a():
    pass

def func(cls, some_other_argument):
    return some_other_argument

setattr(a, 'func', classmethod(func))

if __name__ == "__main__":
    print(a.func)
    print(a.func("asdf"))
Run Code Online (Sandbox Code Playgroud)

返回以下输出

<bound method type.func of <class '__main__.a'>> …
Run Code Online (Sandbox Code Playgroud)

python static-methods metaprogramming class setattr

58
推荐指数
2
解决办法
5万
查看次数

动态创建方法和装饰器,得到错误'functools.partial'对象没有属性'__module__'

我目前正在使用EndpointsModel为AppEngine上的所有模型创建RESTful API.由于它是RESTful,这些api有很多重复代码,我想避免

例如:

class Reducer(EndpointsModel):
    name = ndb.StringProperty(indexed=False)

@endpoints.api(
    name="bigdata",
    version="v1",
    description="""The BigData API""",
    allowed_client_ids=ALLOWED_CLIENT_IDS,
)
class BigDataApi(remote.Service):
    @Reducer.method(
        path="reducer",
        http_method="POST",
        name="reducer.insert",
        user_required=True,
    )
    def ReducerInsert(self, obj):
        pass

    ## and GET, POST, PUT, DELETE
    ## REPEATED for each model
Run Code Online (Sandbox Code Playgroud)

我想让它们变得通用.所以我尝试动态添加方法到类.到目前为止我尝试了什么:

from functools import partial, wraps

def GenericInsert(self, obj, cls):
    obj.owner = endpoints.get_current_user()
    obj.put()
    return obj

# Ignore GenericDelete, GenericGet, GenericUpdate ...

import types
from functools import partial

def register_rest_api(api_server, endpoint_cls):
    name = endpoint_cls.__name__

    # create list method 
    query_method = types.MethodType( …
Run Code Online (Sandbox Code Playgroud)

python google-app-engine functools google-cloud-endpoints endpoints-proto-datastore

18
推荐指数
2
解决办法
8256
查看次数

在Python中动态分配函数实现

我想动态分配一个函数实现.

让我们从以下开始:

class Doer(object):

    def __init__(self):
        self.name = "Bob"

    def doSomething(self):
        print "%s got it done" % self.name

def doItBetter(self):
    print "Done better"
Run Code Online (Sandbox Code Playgroud)

在其他语言中,我们将使doItBetter成为匿名函数并将其分配给对象.但是不支持Python中的匿名函数.相反,我们将尝试创建一个可调用的类实例,并将其分配给该类:

class Doer(object):

    def __init__(self):
        self.name = "Bob"

class DoItBetter(object):

    def __call__(self):
        print "%s got it done better" % self.name

Doer.doSomething = DoItBetter()
doer = Doer()
doer.doSomething()
Run Code Online (Sandbox Code Playgroud)

这给了我这个:

回溯(最近一次调用最后一次):第13行,在doer.doSomething()第9行,在调用 打印"%s让它做得更好"%self.name AttributeError:'DoItBetter'对象没有属性'name'

最后,我尝试将callable作为属性分配给对象实例并调用它:

class Doer(object):

    def __init__(self):
        self.name = "Bob"

class DoItBetter(object):

    def __call__(self):
        print "%s got it done better" % self.name


doer = Doer()
doer.doSomething = …
Run Code Online (Sandbox Code Playgroud)

python anonymous-methods callable anonymous-function

13
推荐指数
2
解决办法
8417
查看次数

我可以在Python中替换对象的现有方法吗?

问:有没有办法在Python(3.6)中改变现有对象的方法?("方法"是指self作为参数传递的函数.)


假设我有一个类Person有一些非常有用的方法SayHi():

class Person(object):
    Cash = 100
    def HasGoodMood(self):
        return self.Cash > 10

    def SayHi(self):
        if self.HasGoodMood():
            print('Hello!')
        else:
            print('Hmpf.')

>>> joe = Person()
>>> joe.SayHi()
Hello!
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,人的反应取决于他们通过该方法计算的当前情绪HasGoodMood().默认情况下,只要他们有10美元以上的现金,他们就会心情愉快.

我可以很容易地创造一个不关心金钱并且一直很开心的人:

>>> joe.HasGoodMood = lambda: True
>>> joe.SayHi()
Hello!
>>> joe.Cash = 0
>>> joe.SayHi()
Hello!
Run Code Online (Sandbox Code Playgroud)

凉.请注意Python如何知道在使用原始实现时HasGoodMood,它会以静默方式self作为第一个参数传递,但如果我将其更改为lambda: True,则会调用不带参数的函数.问题是:如果我想更改HasGoodMood另一个也接受self作为参数的函数的默认值,该怎么办?

让我们继续我们的例子:如果我想创造一个Person只有超过100美元的贪婪的人呢?我想做的事情如下:

>>> greedy_jack = Person()
>>> greedy_jack.HasGoodMood = lambda self: self.Cash > …
Run Code Online (Sandbox Code Playgroud)

python methods python-3.x

12
推荐指数
2
解决办法
2007
查看次数

猴子修补与部分功能

我正在尝试SomeClass从导入的包中对一个方法进行monkeypatch :

from somepackage import SomeClass

def newmethod(obj, node, **kwargs):
    """ """

SomeClass.oldmethod = newmethod
Run Code Online (Sandbox Code Playgroud)

在哪里objnode在默认调用签名SomeClass.oldmethod:

class SomeClass(object):

    def oldmethod(obj, node):
        """ """  
Run Code Online (Sandbox Code Playgroud)

我知道monkeypatching不是一个好习惯,但我们需要一个解决方法,同时我们解决了一些无法解决的问题.上面的方法很有效,但是我们想用部分函数来做这件事.例如:

from functools import partial
newmethod_a = partial(newmethod, foo='a')
newmethod_b = partial(newmethod, foo='b')
Run Code Online (Sandbox Code Playgroud)

调用部分函数是因为我们需要传递不同的**kwargs.但是当我现在尝试超载时:

SomeClass.oldmethod = newmethod_a
Run Code Online (Sandbox Code Playgroud)

我得到一个与传递的参数数量相关的错误,但它非常特定于我的问题所以粘贴它可能没有帮助...我认为错误与oldmethod采取两个位置参数(obj, node)和我的部分的调用签名有关功能不传递到一基准objnode正确.我尝试了不同的结构,如:

newmethod_a = partial(SomeClass.newmethod, foo='a')
Run Code Online (Sandbox Code Playgroud)

对不起,我无法生成一个最小的工作示例.我希望也许专家会从经验中认识到这个问题,并告诉我,如果我在尝试的范围内甚至是可能的partial.

谢谢

python monkeypatching partials

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

如何向Python中现有的类添加方法?

我有一个非常方便的高级pd.DataFrame保存功能,我想添加到pandas. 如何将这个方法添加到类中pd.DataFrame

def to_file(df, path, sep="\t", compression="infer", pickled="infer", verbose=False, **args):
    _ , ext = os.path.splitext(path)
    # Serialization
    if pickled == "infer":
        if ext in {".pkl", ".pgz", ".pbz2"}:
            pickled = True
        else:
            pickled = False
    # Compression
    if compression == "infer":
        if pickled:
            if ext == ".pkl":
                compression = None
            if ext == ".pgz":
                compression = "gzip"
            if ext == ".pbz2":
                compression = "bz2"
        else:
            compression = None
            if path.endswith(".gz"):
                compression = "gzip"
            if path.endswith(".bz2"): …
Run Code Online (Sandbox Code Playgroud)

python methods class object pandas

10
推荐指数
1
解决办法
9427
查看次数

将方法动态附加到使用swig生成的现有Python对象?

我正在使用Python类,并且我没有对其声明的写入权限.如何__str__在不修改类声明的情况下将自定义方法(如)附加到从该类创建的对象中?

编辑:谢谢你的所有答案.我尝试了所有这些,但他们没有解决我的问题.这是一个最小的例子,我希望能澄清这个问题.我使用swig来包装C++类,目的是覆盖swig模块返回的对象__str__功能.我使用cmake来构建示例:

test.py

import example

ex = example.generate_example(2)

def prnt(self):
    return str(self.x)

#How can I replace the __str__ function of object ex with prnt?
print ex
print prnt(ex)
Run Code Online (Sandbox Code Playgroud)

example.hpp

struct example
{
    int x;
};

example generate_example(int x);
Run Code Online (Sandbox Code Playgroud)

example.cpp

#include "example.hpp"
#include <iostream>

example generate_example(int x)
{
    example ex;
    ex.x = x;
    return ex;
}

int main()
{
    example ex = generate_example(2);
    std::cout << ex.x << "\n";
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

example.i

%module example

%{ …
Run Code Online (Sandbox Code Playgroud)

python methods class dynamic

9
推荐指数
1
解决办法
4084
查看次数

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
查看次数