chapter 14_1 环境

本文深入探讨Lua语言中全局变量的存储方式及其环境table,介绍如何使用动态名字访问和设置全局变量,包括使用getfield和setfield函数处理复杂字段名。

  Lua将其所有的全局变量保存在一个常规的table中,称为“global environment”。

Lua将环境table自身保存在一个全局变量_G中,_G._G等于 _G .

比如下面的代码打印出_G中所有的全局变量:

for n in pairs(_G) do 
    print(n)
end

具有动态名字的全局变量

  对于访问和设置全局变量,通常赋值操作就可以了。不过,有时也会用到一些元编程的形式。

当操作一个全局变量时,而它的名称却存储在另一个变量中,或者需要通过运行时的计算才能得到。

为了获取这个变量的值,往往这样写:

value = loadstring("return " .. varname)()

如果varname是x,那么结果就是字符串"return x ".

然而,这段代码中包含了一个新程序块的创建和编译。因此可以使用以下代码来完成相同的效果,但效率上要高出一个数量级:

value = _G[varname]

正因为环境是一个常规的table,才可以使用一个key去直接索引它。类似地,还可以动态计算一个名称,然后将一个值赋予该名称的全局变量:

_G[varname] = value

不过注意,有些程序员对于该技能的运用有些过度,可能写出

_G["a"] = _G["var1"]

其实就是简单一句 a = var1。

  上面的问题的一般化形式是,允许使用动态的字段名,如“io.read" 或 "a.b.c.d"。

如果直接写_G["io.read"]则不会从table io 中得到字段read。但可以写一个函数getfield来实现这个效果。

即通过调用getfield("io.read") 返回所要求的结果。这个函数是一个循环,从_G开始逐个字段地深入求值:

function getfield(f)
    local v=_G        --从全局变量的table开始
    for w in string.gmatch(f,"[%w_]+") do
        v = v[w]
    end
    return v
end

依靠string库中的gmatch来遍历 f 中所有的单词。

与之对应的设置字段的函数则稍显复杂。像a.b.c.d = v 这样的赋值等价于以下代码:

local  temp = a.b.c
temp.d = v

也就是说,必须一直检索到最后一个名称,然后分别进行操作。下面这个函数setfield就完成了这项任务,并且创建路径中间那些不存在的table。

function setfield(f,v)
    local t = _G                --从全局变量的table开始
    for w , d in string.gmatch ( f ,"([%w_]+) (%.?)" )  do
        if d == "." then        --是最后一个字段吗?
            t[w] = t[w] or {}   --如果不存在就创建table
            t = t[w]            --获取该table
        else
            t[w] = v
        end
    end
end

上例中用到了一种字符串模式,通过这种模式就可以将字段名捕获到变量w中,并将一个可选的句号捕获到d中。

调用上面的这个函数:

setfield("t.x.y",10)

便创建了两个table:全局 t 和 t.x ,并将10赋值给t.x.y :

print(t.x.y)             --> 10
print(getfield("t.x.y"))    --> 10

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

 

转载于:https://www.cnblogs.com/daiker/p/5853906.html

我的代码:import rclpy from rclpy.node import Node from chapter4_interfaces.srv import FaceDetector from ament_index_python.packages import get_package_share_directory from cv_bridge import CvBridge #用于转换格式,opencv和ros的格式不同 import cv2 import face_recognition import time import os class FaceDetectNode(Node): def __init__(self): super().__init__('face_detect_node') self.service = self.create_service(FaceDetector,'face_detect',self.face_detect_callback) self.bridge = CvBridge() self.number_of_times_to_upsample = 1 self.model = 'hog' self.default_image_path = os.path.join(get_package_share_directory('demo_python_service'), 'resource/default.jpg') self.get_logger().info("人脸检测服务启动!") def face_detect_callback(self,request,response): #判断请求的图像数据是否为空: #如果不为空,则使用bridge的方法imgmsg_to_cv2,将图像转化成opencv的格式; #如果图像为空,则直接从默认文件路径读取图像。 if request.image.data: cv_image = self.bridge.imgmsg_to_cv2(request.image) else: cv_image = cv2.imread(self.default_image_path) self.get_logger().info(f"传入图像为空,使用默认图像!") start_time = time.time() self.get_logger().info(f"加载完成图像,开始检测!") #查找图像中的所有人脸(图像,上采样次数,使用的训练模型) face_locations = face_recognition.face_locations(cv_image, number_of_times_to_upsample = self.number_of_times_to_upsample, model =self.model) #检测耗时 response.use_time = time.time() - start_time #人脸数量 response.number = len(face_locations) for top, right, bottom, left in face_locations: response.top.append(top) response.right.append(right) response.bottom.append(bottom) response.left.append(left) return response def main(args=None): rclpy.init(args=args) node = FaceDetectNode() rclpy.spin(node) rclpy.shutdown(),会报错:Traceback (most recent call last): File "/home/ubuntu20/FishRos_Learn/chapter4/chapter4_ws/install/demo_python_service/lib/demo_python_service/face_detect_node", line 11, in <module> load_entry_point('demo-python-service==0.0.0', 'console_scripts', 'face_detect_node')() File "/home/ubuntu20/FishRos_Learn/chapter4/chapter4_ws/install/demo_python_service/lib/python3.8/site-packages/demo_python_service/face_detect_node.py", line 50, in main node = FaceDetectNode() File "/home/ubuntu20/FishRos_Learn/chapter4/chapter4_ws/install/demo_python_service/lib/python3.8/site-packages/demo_python_service/face_detect_node.py", line 14, in __init__ self.service = self.create_service(FaceDetector,'face_detect',self.face_detect_callback) File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/node.py", line 1300, in create_service check_for_type_support(srv_type) File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/type_support.py", line 29, in check_for_type_support msg_type.__class__.__import_type_support__() File "/home/ubuntu20/FishRos_Learn/chapter4/chapter4_ws/install/chapter4_interfaces/lib/python3.8/site-packages/chapter4_interfaces/srv/_face_detector.py", line 437, in __import_type_support__ _face_detector.Metaclass_FaceDetector_Request.__import_type_support__() File "/home/ubuntu20/FishRos_Learn/chapter4/chapter4_ws/install/chapter4_interfaces/lib/python3.8/site-packages/chapter4_interfaces/srv/_face_detector.py", line 44, in __import_type_support__ if Image.__class__._TYPE_SUPPORT is None: AttributeError: type object 'type' has no attribute '_TYPE_SUPPORT'
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值