python如何实现类似指针概念_在Python中模拟实现指针

在Python中模拟实现指针

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

这里用两种方法来实现:

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

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

使用可变类型作为指针

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

* x  + =  1 ;

}

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

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 "", line 1, in 

File "", 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值