我想要这样的效果:
ans.vote --> 返回数目 ans.vote() --> 赞同答案
可是具体操作时却这样: TypeError: 'NoneType' object is not callable
class Ans(object):
def __init__(self ):
pass
def vote(self):
print('赞同他')
@property
def vote(self):
print('获取赞同'+str(self._vote))
Ans().vote
>> '获取赞同9'
Ans().vote(2)
>>TypeError: 'NoneType' object is not callable
我又试了一下:
class aaa(object):
def __init__(self):
pass
def __get__(self, instance, owner):
print('get')
def __call__(self, *arg):
print('call')
class ccc(object):
"""docstring for ccc"""
a = aaa()
def __init__(self):
pass
aaa()()
>> get
ccc().a
>> get
ccc().a()
>> TypeError: 'NoneType' object is not callable
def intcan(call):
def allcan_func(f):
class allcan_class(int):
def __call__(self, instance, *args, **kwargs):
return call(instance)
def __get__(self, instance, owner):
return allcan_class(f(instance))
return allcan_class()
return allcan_func
最后用这个装饰器实现了ans.vote,ans.vote()
的功能
但是有个问题,调用ans.vote的时候会自动调用ans.vote值的相关代码,不知道怎么解决
1
hlwjia 2018-07-21 15:21:55 +08:00
你的 ans 是 None ?
|
2
mimzy 2018-07-21 15:26:44 +08:00
Python 没有重载(可能不严格,请指正),因为有可变参数和默认参数。
你的 ans 或者实例中的某些东西是 None |
3
Cheez OP 不是 None,具体见附言.
|
4
u2386 2018-07-21 15:39:13 +08:00 1
|
5
Trim21 2018-07-21 15:41:52 +08:00 1
class vote(int):
def __call__(self, *args, **kwargs): print('vote') pass class a(object): vote = vote(1) ans = a() print(ans.vote) ans.vote() |
6
u2386 2018-07-21 15:41:52 +08:00 2
附言里加了 property 的 vote 覆盖了上一个 vote 方法,并且只有 print,没有 return,所以调用这个方法返回是个 None。
|
7
Cheez OP |
8
ipwx 2018-07-21 17:25:53 +08:00
强烈反对楼主的做法。
|
10
yezhiye 2018-07-21 18:25:57 +08:00 via Android
这样做挺奇怪的,因为可以定义函数 func def func()...然后 a = func,这样就可以通过 a()执行 func。如果名字一样的话就覆盖了。
|
12
Cheez OP def intcan(call):
def allcan_func(f): class allcan_class(int): def __call__(self, instance, *args, **kwargs): return call(instance) def __get__(self, instance, owner): return allcan_class(f(instance)) return allcan_class() return allcan_func 最后用这个装饰器实现了 ans.vote,ans.vote()的功能 但是有个问题,调用 ans.vote 的时候会自动调用 ans.vote 值的相关代码,不知道怎么解决 @Trim21 #5 @yezhiye @ipwx #8 @u2386 #4 |
14
Cheez OP |
17
mingyun 2018-07-21 22:43:01 +08:00
函数里定义类 python 有点怪
|
18
gnijuohz 2018-07-21 23:19:44 +08:00 via iPhone
不太明白为什么非要都用 vote 这词
从语法上讲名词( property )用 votes 这个复数形式更恰当 然后进行投票用 vote |
19
wangyongbo 2018-07-21 23:49:33 +08:00 1
这两天升级 django , 从 1.8 升级到 支持 python2.7 的最后一个版本 1.11.
发现 "Using user.is_authenticated() and user.is_anonymous() as a method " "is deprecated. Remove the parentheses to use it as an attribute.", 之前的使用方法:user.is_authenticated() 现在的使用方法:user.is_authenticated 我看了一下 django 的实现方法 ``` class User(): @property def is_authenticated(self): return CallableFalse ``` 首先用 property 把它变成了一个属性,但是返回的不是一个 bool, 是一个有__call__ 的对象 CallableFalse = CallableBool(False) ``` class CallableBool: """ An boolean-like object that is also callable for backwards compatibility. """ do_not_call_in_templates = True def __init__(self, value): self.value = value def __bool__(self): return self.value def __call__(self): warnings.warn( "Using user.is_authenticated() and user.is_anonymous() as a method " "is deprecated. Remove the parentheses to use it as an attribute.", RemovedInDjango20Warning, stacklevel=2 ) return self.value def __nonzero__(self): # Python 2 compatibility return self.value def __repr__(self): return 'CallableBool(%r)' % self.value def __eq__(self, other): return self.value == other def __ne__(self, other): return self.value != other def __or__(self, other): return bool(self.value or other) def __hash__(self): return hash(self.value) ``` 你觉得这种实现方式 怎么样? 出了 这种需要兼容的代码, 再也没有见过 类似的代码了。 |
20
wangyongbo 2018-07-21 23:52:17 +08:00
|
23
Cheez OP 因为问题始终无法解决,最后换成了这种写法:
``` def vote(self): print('赞同他') self.vote.__dict__['count'] = self._vote return self ``` 调用的时候: ``` print('方法') print(Article('37208344').vote()) print('属性') print(Article('37208344').vote.count) ``` @ipwx #21 @wangyongbo #19 @Trim21 #15 |
24
laike9m 2018-07-22 12:01:54 +08:00 via Android
这接口设计也是醉了,弄个叫 vote_count 的 property 不好么
|