我试图了解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)
为什么我需要描述符类?请使用此示例或您认为更好的示例进行说明.
什么是instance和owner这里?(in __get__).所以我的问题是,第三个参数的目的是什么?
我该怎么称呼/使用这个例子?
我希望在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) 我目前正在使用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
我想动态分配一个函数实现.
让我们从以下开始:
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(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) 我正在尝试SomeClass从导入的包中对一个方法进行monkeypatch :
from somepackage import SomeClass
def newmethod(obj, node, **kwargs):
""" """
SomeClass.oldmethod = newmethod
Run Code Online (Sandbox Code Playgroud)
在哪里obj和node在默认调用签名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)和我的部分的调用签名有关功能不传递到一基准obj和node正确.我尝试了不同的结构,如:
newmethod_a = partial(SomeClass.newmethod, foo='a')
Run Code Online (Sandbox Code Playgroud)
对不起,我无法生成一个最小的工作示例.我希望也许专家会从经验中认识到这个问题,并告诉我,如果我在尝试的范围内甚至是可能的partial.
谢谢
我有一个非常方便的高级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类,并且我没有对其声明的写入权限.如何__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) 我正在尝试修补类实例,但是我不太清楚如何修补类方法没问题.
>>> 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 ×10
class ×3
methods ×3
callable ×1
descriptor ×1
dynamic ×1
functools ×1
object ×1
pandas ×1
partials ×1
python-3.x ×1
reflection ×1
runtime ×1
setattr ×1