Python 的传址和传值疑问 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
qsnow6

Python 的传址和传值疑问

  •  
  •   qsnow6 2017 年 2 月 21 日 3048 次点击
    这是一个创建于 3349 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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?

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

    第 1 条附言    2017 年 2 月 21 日

    是这样,这个类是一个库里随机生成 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() 
    24 条回复    2017-02-21 22:12:22 +08:00
    cheetah
        1
    cheetah  
       2017 年 2 月 21 日
    你是想每次使用 a 的时候产生一个新随机数?

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

    这样?
    qsnow6
        2
    qsnow6  
    OP
       2017 年 2 月 21 日
    @cheetah 对啊~~`
    qsnow6
        3
    qsnow6  
    OP
       2017 年 2 月 21 日
    @cheetah 应该怎么传
    cheetah
        4
    cheetah  
       2017 年 2 月 21 日
    @qsnow6 我认为做不到。坐等楼下黑科技。
    binux
        5
    binux  
       2017 年 2 月 21 日
    ```
    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
        6
    cheetah  
       2017 年 2 月 21 日
    @binux 这个 a 只能用来打印了 = =
    qsnow6
        7
    qsnow6  
    OP
       2017 年 2 月 21 日
    @binux 在不修改他原来的类的情况下,有没有办法引用他这个 f.random
    binux
        8
    binux  
       2017 年 2 月 21 日
    @cheetah #6 挨个写, __add__,__str__, __eq__ ...
    因为 LZ 并没有说「调用 a 」是什么意思,比如 b = a ,这是在拷贝 a 还是在调用 a ?
    binux
        9
    binux  
       2017 年 2 月 21 日
    @qsnow6 #7 这是一个 XY 问题
    Allianzcortex
        10
    Allianzcortex  
       2017 年 2 月 21 日
    你的 __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
        11
    cheetah  
       2017 年 2 月 21 日
    @Allianzcortex 最后两行应该是 `a()` 吧
    Herobs
        12
    Herobs  
       2017 年 2 月 21 日
    obj.x 这种形式还可以用描述器,直接访问变量 x 这种形式应该是没有办法做到吧。
    eccstartup
        13
    eccstartup  
       2017 年 2 月 21 日
    不懂,但是有点像 scheme 里 quote , eval 这些东西
    qsnow6
        14
    qsnow6  
    OP
       2017 年 2 月 21 日
    @Allianzcortex
    是这样,这个类是一个库里随机生成 UserAgent 的方法 ;
    我有一个爬虫,代码里面的变量是写好的,比如 self.user_agent
    爬虫每次请求都会把 self.user_agent 作为自己的 useragent

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

    但是,发现是直接传的值过去,每次生成的内容是一样的。。
    qsnow6
        15
    qsnow6  
    OP
       2017 年 2 月 21 日
    看了下原来的 ua.random 的实现就是通过 __getattr__ 来实现的
    qsnow6
        16
    qsnow6  
    OP
       2017 年 2 月 21 日
    好了,再套一个类上去就搞定了


    class MyFun(object):

    def __repr__(self):

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

    f = MyFun()
    binux
        17
    binux  
       2017 年 2 月 21 日   1
    @qsnow6 #16 不不不,__repr__ 是搞笑的,要么改 self 对应类的 __get_attr__,要么用 __get__,具体见 https://docs.python.org/2/howto/descriptor.html
    binux
        18
    binux  
       2017 年 2 月 21 日
    forrestchang
        19
    forrestchang  
       2017 年 2 月 21 日
    看了一下,大致明白了 lz 的意思。

    你是要每次都 generate 一个新的 UserAgent ?

    直接定义一个 gen_ua() 不就好了,

    def gen_ua():
    return UserAgent().random

    然后

    self.user_agent = gen_ua()
    qsnow6
        20
    qsnow6  
    OP
       2017 年 2 月 21 日
    @forrestchang 函数返回的是值,调用 self.user_agent 是不会变的,嘻嘻,刚开始我也没转过来
    forrestchang
        21
    forrestchang  
       2017 年 2 月 21 日
    @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.
    ericls
        22
    ericls  
       2017 年 2 月 21 日 via iPhone
    Python 是按 assignment 传的
    junnplus
        23
    junnplus  
       2017 年 2 月 21 日
    property 应该是正解吧
    Allianzcortex
        24
    Allianzcortex  
       2017 年 2 月 21 日
    @cheetah Yep !!! a()!!!
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1063 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 57ms UTC 23:10 PVG 07:10 LAX 16:10 JFK 19:10
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86