最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 在Python中模拟实现指针

    正文概述    2020-08-12   208

    在Python中模拟实现指针

    因为Python中的指针本身不存在,但并不意味着无法使用指针。实际上有多种方法可以在Python中模拟指针。

    这里用两种方法来实现:

    使用可变类型作为指针【Python中的变量】

    使用自定义Python对象【Python中的对象】

    在Python中模拟实现指针

    使用可变类型作为指针

    您已经了解了可变类型。因为这些对象是可变的,所以您可以将它们视为指向模拟指针行为的指针。假设您要复制以下c代码:

    void  add_one (int  * x ) { 
        * x  + =  1 ; 
    }

    此代码采用指向整数(*x)的指针,然后将该值递增1。这是一个练习代码的主要功能:

    #include <stdio.h>
    int main(void) {
        int y = 2337;
        printf("y = %d\n", y);
        add_one(&y);
        printf("y = %d\n", y);
        return 0;
    }

    在上面的代码中,分配2337给y,打印出当前值,将值递增1,然后打印出修改后的值。执行此代码的输出如下:

    y = 2337 
    y = 2338

    在Python中复制此类行为的一种方法是使用可变类型。考虑使用列表并修改第一个元素:

    >>> def  add_one (x ):
    ...     x [ 0 ]  + =  1 
    ... 
    >>> y  =  [ 2337 ] 
    >>> add_one (y )
    >>> y [ 0 ] 
    2338

    在这里,add_one(x)访问第一个元素并将其值增加1。使用一种list方法,最终结果似乎已修改了该值。那么Python中的指针确实存在吗?好吧,这是唯一可能的,因为它list是一种可变类型。如果您尝试使用a tuple,则会收到错误消息:

    >>> z = (2337,)
    >>> add_one(z)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "<stdin>", line 2, in add_one
    TypeError: 'tuple' object does not support item assignment

    上面的代码演示了这tuple是不可变的。因此,它不支持项目分配。list不是唯一可变的类型。在Python中模仿指针的另一种常见方法是使用a dict。

    假设您有一个应用程序,您希望每次发生有趣事件时都要跟踪它。实现此目的的一种方法是创建一个dict并使用其中一个项目作为计数器:

    >>> counters = {"func_calls": 0}
    >>> def bar():
    ...     counters["func_calls"] += 1
    ...
    >>> def foo():
    ...     counters["func_calls"] += 1
    ...     bar()
    ...
    >>> foo()
    >>> counters["func_calls"]
    2

    在此示例中,counters字典用于跟踪函数调用的数量。打电话后foo(),计数器已2按预期增加。所有因为dict是可变的。

    请记住,这只是模拟指针行为,并不直接映射到C或C ++中的真指针。也就是说,这些操作比在C或C ++中更昂贵。

    使用Python对象

    该dict选项是在Python中模拟指针的好方法,但有时记住您使用的密钥名称会很繁琐。如果您在应用程序的各个部分使用字典,则尤其如此。这是自定义Python类可以真正帮助的地方。

    要构建最后一个示例,假设您要跟踪应用程序中的指标。创建一个类是抽象讨厌细节的好方法:

    class  Metrics (object ):
        def  __init __ (self ):
            self 。_metrics  =  { 
                “func_calls” : 0 ,
                “cat_pictures_served” : 0 ,
            }

    此代码定义了一个Metrics类。该类仍然使用a dict来保存实际数据,该数据位于_metrics成员变量中。这将为您提供所需的可变性。现在您只需要能够访问这些值。一个很好的方法是使用属性:

    class Metrics(object):
        # ...
        @property
        def func_calls(self):
            return self._metrics["func_calls"]
        @property
        def cat_pictures_served(self):
            return self._metrics["cat_pictures_served"]

    这段代码利用了@property。如果您不熟悉装饰器,可以在Python装饰器上查看这个Primer。@property这里的装饰器允许您访问func_calls,cat_pictures_served就像它们是属性一样:

    >>> metrics = Metrics()
    >>> metrics.func_calls
    0
    >>> metrics.cat_pictures_served
    0

    您可以将这些名称作为属性访问这一事实意味着您抽象出这些值在a中的事实dict。您还可以更明确地了解属性的名称。当然,您需要能够增加这些值:

    class Metrics(object):
        # ...
        def inc_func_calls(self):
            self._metrics["func_calls"] += 1
        def inc_cat_pics(self):
            self._metrics["cat_pictures_served"] += 1

    这里再介绍两种新方法:

    inc_func_calls()
    inc_cat_pics()

    这些方法会修改指标中的值dict。您现在有一个类可以修改,就像您正在修改指针一样:

    >>> metrics = Metrics()
    >>> metrics.inc_func_calls()
    >>> metrics.inc_func_calls()
    >>> metrics.func_calls
    2

    在这里,您可以在应用程序中的各个位置访问func_calls和调用inc_func_calls(),并在Python中模拟指针。当您需要在应用程序的各个部分中频繁使用和更新指标时,这非常有用。

    注意:特别是在这个类中,make inc_func_calls()和inc_cat_pics()explicit而不是使用@property.setter阻止用户将这些值设置为任意int或无效的值,如dict。

    class Metrics(object):
        def __init__(self):
            self._metrics = {
                "func_calls": 0,
                "cat_pictures_served": 0,
            }
        @property
        def func_calls(self):
            return self._metrics["func_calls"]
        @property
        def cat_pictures_served(self):
            return self._metrics["cat_pictures_served"]
        def inc_func_calls(self):
            self._metrics["func_calls"] += 1
        def inc_cat_pics(self):
            self._metrics["cat_pictures_served"] += 1

    起源地下载网 » 在Python中模拟实现指针

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元