import random
class MyFun(object):
def __getattr__(self, key):
if key == 'random':
return random.random()
else:
pass
f = MyFun()
f.random
如上代码
如何把 f.random 传给一个变量,比如a
,然后以后调用 a 就执行 f.random?
试过浅拷贝、深拷贝都没用。。
是这样,这个类是一个库里随机生成 UserAgent 的方法 ua.random
我有一个爬虫,里面的变量是写好的,比如 self.user_agent
爬虫每次请求都会把self.user_agent作为自己的 User-Agent
所以我就想让把ua.random 传给self.user_agent,这样,就可以不变更原来的代码的情况下,实现自动更换useragent
原来的 ua.random 的实现就是通过 getattr 来实现的,发现无论是深拷贝还是浅拷贝,倒过去的是值,没法直接引用ua.random
self.user_agent = ua.random
UPDATE 直接在原来的基础上套了一个类,也算是实现了;)
class MyFun(object):
def __repr__(self):
from fake_useragent import UserAgent
ua = UserAgent()
return ua.random
f = MyFun()
1
cheetah 2017-02-21 18:52:22 +08:00
你是想每次使用 a 的时候产生一个新随机数?
``` >>> a 0.14750847086722485 >>> a 0.822349231203261 ``` 这样? |
5
binux 2017-02-21 19:01:34 +08:00
```
In [6]: class A(): ...: def __repr__(self): ...: return str(random.random()) ...: a = A() ...: In [7]: a Out[7]: 0.313638352347 In [8]: a Out[8]: 0.00887313470731 ``` |
8
binux 2017-02-21 19:08:29 +08:00
@cheetah #6 挨个写, __add__,__str__, __eq__ ...
因为 LZ 并没有说「调用 a 」是什么意思,比如 b = a ,这是在拷贝 a 还是在调用 a ? |
10
Allianzcortex 2017-02-21 19:12:29 +08:00
你的 __getattr__ 是做什么的。。。我觉得按照描述是做不到,但如果不一致性要求的话可以试试用 __call__() 来把类模型为函数:
``` import random class MyFun(object): def __getattr__(self, key): if key == 'random': return random.random() else: pass def __call__(self): return random.random() a = MyFun() a # randomnumber 1 a # randomnumber 2 ``` 但这和直接调 random 方法有什么区别啊。。。。 |
11
cheetah 2017-02-21 19:16:53 +08:00
@Allianzcortex 最后两行应该是 `a()` 吧
|
12
Herobs 2017-02-21 19:18:59 +08:00
obj.x 这种形式还可以用描述器,直接访问变量 x 这种形式应该是没有办法做到吧。
|
13
eccstartup 2017-02-21 19:25:02 +08:00
不懂,但是有点像 scheme 里 quote , eval 这些东西
|
14
qsnow6 OP @Allianzcortex
是这样,这个类是一个库里随机生成 UserAgent 的方法 ; 我有一个爬虫,代码里面的变量是写好的,比如 self.user_agent 爬虫每次请求都会把 self.user_agent 作为自己的 useragent 所以我就想直接让 self.user_agent 每次都引用 ua.random 但是,发现是直接传的值过去,每次生成的内容是一样的。。 |
15
qsnow6 OP 看了下原来的 ua.random 的实现就是通过 __getattr__ 来实现的
|
16
qsnow6 OP 好了,再套一个类上去就搞定了
class MyFun(object): def __repr__(self): from fake_useragent import UserAgent ua = UserAgent() return ua.random f = MyFun() |
17
binux 2017-02-21 19:51:37 +08:00 1
@qsnow6 #16 不不不,__repr__ 是搞笑的,要么改 self 对应类的 __get_attr__,要么用 __get__,具体见 https://docs.python.org/2/howto/descriptor.html
|
18
binux 2017-02-21 19:53:01 +08:00
|
19
forrestchang 2017-02-21 20:16:04 +08:00
看了一下,大致明白了 lz 的意思。
你是要每次都 generate 一个新的 UserAgent ? 直接定义一个 gen_ua() 不就好了, def gen_ua(): return UserAgent().random 然后 self.user_agent = gen_ua() |
20
qsnow6 OP @forrestchang 函数返回的是值,调用 self.user_agent 是不会变的,嘻嘻,刚开始我也没转过来
|
21
forrestchang 2017-02-21 20:38:53 +08:00
@qsnow6 那么这个样子呢,改成计算属性好了
class WTF(object): def __init__(self): pass @property def user_agent(self): return UserAgent().random wtf = WTF() wtf.user_agent # call user_agent() __repr__ 不是像你这么用的 Called by the repr() built-in function to compute the “ official ” string representation of an object. If at all possible, this should look like a valid Python expression that could be used to recreate an object with the same value (given an appropriate environment). If this is not possible, a string of the form <...some useful description...> should be returned. The return value must be a string object. |
22
ericls 2017-02-21 21:06:44 +08:00 via iPhone
Python 是按 assignment 传的
|
23
junnplus 2017-02-21 21:29:44 +08:00
property 应该是正解吧
|
24
Allianzcortex 2017-02-21 22:12:22 +08:00
@cheetah Yep !!! a()!!!
|