Python 的传址和传值疑问

2017-02-21 18:47:40 +08:00
 qsnow6
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?

试过浅拷贝、深拷贝都没用。。

2510 次点击
所在节点    Python
24 条回复
cheetah
2017-02-21 18:52:22 +08:00
你是想每次使用 a 的时候产生一个新随机数?

```
>>> a
0.14750847086722485
>>> a
0.822349231203261
```

这样?
qsnow6
2017-02-21 18:53:06 +08:00
@cheetah 对啊~~`
qsnow6
2017-02-21 18:54:05 +08:00
@cheetah 应该怎么传
cheetah
2017-02-21 18:57:39 +08:00
@qsnow6 我认为做不到。坐等楼下黑科技。
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
```
cheetah
2017-02-21 19:04:33 +08:00
@binux 这个 a 只能用来打印了 = =
qsnow6
2017-02-21 19:06:27 +08:00
@binux 在不修改他原来的类的情况下,有没有办法引用他这个 f.random
binux
2017-02-21 19:08:29 +08:00
@cheetah #6 挨个写, __add__,__str__, __eq__ ...
因为 LZ 并没有说「调用 a 」是什么意思,比如 b = a ,这是在拷贝 a 还是在调用 a ?
binux
2017-02-21 19:09:45 +08:00
@qsnow6 #7 这是一个 XY 问题
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 方法有什么区别啊。。。。
cheetah
2017-02-21 19:16:53 +08:00
@Allianzcortex 最后两行应该是 `a()` 吧
Herobs
2017-02-21 19:18:59 +08:00
obj.x 这种形式还可以用描述器,直接访问变量 x 这种形式应该是没有办法做到吧。
eccstartup
2017-02-21 19:25:02 +08:00
不懂,但是有点像 scheme 里 quote , eval 这些东西
qsnow6
2017-02-21 19:34:03 +08:00
@Allianzcortex
是这样,这个类是一个库里随机生成 UserAgent 的方法 ;
我有一个爬虫,代码里面的变量是写好的,比如 self.user_agent
爬虫每次请求都会把 self.user_agent 作为自己的 useragent

所以我就想直接让 self.user_agent 每次都引用 ua.random

但是,发现是直接传的值过去,每次生成的内容是一样的。。
qsnow6
2017-02-21 19:34:46 +08:00
看了下原来的 ua.random 的实现就是通过 __getattr__ 来实现的
qsnow6
2017-02-21 19:47:58 +08:00
好了,再套一个类上去就搞定了


class MyFun(object):

def __repr__(self):

from fake_useragent import UserAgent
ua = UserAgent()
return ua.random

f = MyFun()
binux
2017-02-21 19:51:37 +08:00
@qsnow6 #16 不不不,__repr__ 是搞笑的,要么改 self 对应类的 __get_attr__,要么用 __get__,具体见 https://docs.python.org/2/howto/descriptor.html
binux
2017-02-21 19:53:01 +08:00
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()
qsnow6
2017-02-21 20:23:27 +08:00
@forrestchang 函数返回的是值,调用 self.user_agent 是不会变的,嘻嘻,刚开始我也没转过来

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/342147

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX