python中getattr/setattr/hasattr/delattr函数都是干什么的?

news2024/9/21 4:24:23

目录

1、getattr:动态获取属性 🔍

1.1 动态获取属性

1.2 默认值处理技巧

1.3 实战案例:配置文件动态加载

2、setattr:动态设置属性 🛠

2.1 修改对象属性

2.2 新增属性场景

2.3 应用场景:类的动态配置更新

3、hasattr:检查属性存在与否 🔎

3.1 安全性检查

3.2 条件逻辑简化

4、delattr:删除对象属性 🗑

4.1 属性清理实例

4.2 特殊应用场景:资源清理与状态重置

4.3 警惕:删除属性的副作用

5、综合案例:构建动态属性处理器 🌀

5.1 设计思路解析

功能目标:

设计步骤:

5.2 代码实现与优化

6、深入Python数据模型 📖

6.1 揭秘__getattribute__

6.2 自定义属性访问控制

7、性能考量与最佳实践 ⏱️

7.1 动态属性操作的性能影响

7.2 优化策略:减少动态属性依赖

7.3 实战建议:平衡灵活性与效率

8、总结与展望 🚀



1、getattr:动态获取属性 🔍

1.1 动态获取属性

在Python中,getattr函数是探索和操作对象属性的强大工具。当需要从一个对象中获取属性时,通常我们会直接使用点操作符(.)。然而,在不知道属性名或者属性名由动态变量决定的情况下,getattr就显得尤为实用了。

示例代码:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person('张三', 30)
attr_name = 'name'

print(getattr(p, attr_name))

输出:

张三

在这个例子中,我们创建了一个Person类并实例化了一个Person对象p。通过使用getattr,我们可以根据字符串'name'动态地获取p对象的name属性。

1.2 默认值处理技巧

getattr函数还允许我们指定一个默认值 ,当尝试获取的属性不存在时,这个默认值将被返回。这可以防止程序因为属性不存在而抛出异常,使得代码更加健壮和灵活。

示例代码:

print(getattr(p, 'gender', '未指定'))

输出:

未指定

这里 ,p对象并没有gender属性 ,但是由于我们在getattr调用中指定了默认值'未指定' ,所以程序不会中断,而是返回了这个默认值。

通过getattr函数,开发者能够在不知道具体属性名的情况下灵活地操作对象,同时还能通过设置默认值来增强代码的健壮性。这是Python动态性的一个重要体现,也是面向对象编程中非常实用的功能。

1.3 实战案例:配置文件动态加载

在现实项目中 ,动态加载配置文件中的属性是一种常见的需求。我们可以利用 getattr 来实现这一功能。

假设我们有一个配置类 Config ,其中包含各种配置项,如数据库连接字符串等。下面是如何使用 getattr 来读取这些配置项的示例:

示例代码:

class Config:
    DATABASE_URL = 'postgresql://user:password@localhost:5432/mydatabase'
    API_KEY = 'secret_key_here'

def get_config_value(key, default=None):
    return getattr(Config, key, default)

db_url = get_config_value('DATABASE_URL')
api_key = get_config_value('API_KEY')
secret_token = get_config_value('SECRET_TOKEN', 'default_secret')

print(db_url)
print(api_key)
print(secret_token)

输出:

postgresql://user:password@localhost:5432/mydatabase
secret_key_here
default_secret

这个例子展示了如何使用 getattr 来从 Config 类中动态地获取配置项 ,同时提供了一个默认值以应对配置项可能未定义的情况。这种方法使得我们的代码更加灵活,能够轻松适应不同环境下的配置差异。

2、setattr:动态设置属性 🛠

2.1 修改对象属性

setattr是Python中的一个内置函数,它允许你动态地修改或设置对象的属性值。这在需要根据运行时条件改变对象状态的场景下非常有用。

示例代码:

class Car:
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year

my_car = Car('Toyota', 'Corolla', 2015)

# 修改对象属性
setattr(my_car, 'year', 2020)

print(my_car.year)

输出:

2020

在这个例子中,我们首先定义了一个Car类 ,并创建了一个Car对象my_car。然后,使用setattr函数将my_caryear属性从2015年修改到了2020年 ,展示了动态修改对象属性的能力。

2.2 新增属性场景

除了修改已存在的属性,setattr还可以用来为对象添加全新的属性,这对于设计灵活的数据结构或动态扩展对象功能特别有帮助。

示例代码:

# 继续使用之前的my_car对象
setattr(my_car, 'color', 'Blue')

print(my_car.color)

输出:

Blue

这里 ,我们为my_car对象新增了一个名为color的属性,并赋值为Blue。尽管Car类的初始化中并未包含color属性 ,但通过setattr,我们仍然能够成功地为其添加这一属性。

2.3 应用场景:类的动态配置更新

在复杂的系统中,类的配置可能需要根据外部条件变化而动态调整。setattr 在此类场景下显得尤为有用。比如,在一个应用程序初始化时,可根据配置文件更新类的属性:

示例代码:

class AppConfig:
    debug_mode = False

def update_config_from_file(filename):
    with open(filename, 'r') as file:
        for line in file:
            key, value = line.strip().split('=')
            if hasattr(AppConfig, key):
                setattr(AppConfig, key, eval(value))

update_config_from_file('config.txt')
print(AppConfig.debug_mode)

假设 config.txt 包含 debug_mode=True,此例展示了如何读取配置文件并使用 setattr 更新 AppConfig 的属性值。请注意 ,在实际应用中直接使用 eval 函数可能存在安全风险,应谨慎使用或替换为更安全的解析方式。

3、hasattr:检查属性存在与否 🔎

3.1 安全性检查

hasattr函数在Python中扮演着安全卫士的角色,它用于检查一个对象是否具有特定的属性。这对于编写健壮且可靠的代码至关重要,尤其是在处理可能由外部输入动态变化的对象时。

示例代码:

class Vehicle:
    def __init__(self, name, wheels=None):
        self.name = name
        self.wheels = wheels

car = Vehicle('Toyota Corolla', 4)
plane = Vehicle('Boeing 747')

# 使用hasattr检查属性是否存在
if hasattr(car, 'wheels'):
    print(f"{car.name} has {car.wheels} wheels.")
else:
    print(f"{car.name} does not have wheels.")

if hasattr(plane, 'wheels'):
    print(f"{plane.name} has wheels.")
else:
    print(f"{plane.name} does not have wheels.")

输出:

Toyota Corolla has 4 wheels.
Boeing 747 does not have wheels.

在这个例子中 ,我们定义了一个Vehicle类 ,其中car对象有wheels属性 ,而plane对象没有。通过hasattr函数,我们能够安全地检查和处理这两个对象的不同属性 ,从而避免了潜在的AttributeError

3.2 条件逻辑简化

hasattr不仅提高了代码的安全性 ,还能简化条件逻辑,使得代码更加清晰和易于维护。当需要根据对象是否具有某属性执行不同的逻辑分支时 ,hasattr是一个理想的选择。

示例代码:

def display_vehicle_info(vehicle):
    if hasattr(vehicle, 'wheels'):
        print(f"The vehicle has {vehicle.wheels} wheels.")
    else:
        print("The vehicle does not have wheels information.")

display_vehicle_info(car)
display_vehicle_info(plane)

输出:

The vehicle has 4 wheels.
The vehicle does not have wheels information.

这段代码定义了一个display_vehicle_info函数,它接受一个Vehicle类型的对象作为参数。通过使用hasattr ,函数能够根据不同车辆类型的存在或缺失wheels属性,输出恰当的信息。这样,即使面对不同类型或配置的车辆 ,该函数也能灵活适应,提供正确的输出。

hasattr函数的运用不仅加强了代码的安全防护,还简化了条件判断逻辑,提升了代码的可读性和维护性。掌握这一函数,对于构建高效、健壮的Python应用程序来说,无疑是锦上添花。

4、delattr:删除对象属性 🗑

4.1 属性清理实例

在Python中,delattr函数提供了删除对象属性的能力,这对于资源管理和内存优化尤其关键。当不再需要某个属性时 ,适时清理可以避免不必要的内存占用。

示例代码:

class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password

user = User('Alice', 'SecurePwd123')

# 显示对象初始属性
print(user.__dict__)

# 删除敏感属性
delattr(user, 'password')

# 再次显示对象属性,验证password已被删除
print(user.__dict__)

输出:

{'username': 'Alice', 'password': 'SecurePwd123'}
{'username': 'Alice'}

此例中,我们定义了一个User类 ,实例化后利用delattr函数移除了敏感的password属性 ,确保了数据的安全性,并释放了相关内存空间。

4.2 特殊应用场景:资源清理与状态重置

在一些特殊的应用场景下,delattr 可以用来实现资源的清理工作或对象状态的完全重置。例如,在设计一个管理数据库连接的对象时,可以利用 delattr 来断开连接,以确保资源的及时释放。

示例代码:

class DatabaseConnection:
    def __init__(self, connection_string):
        self.connection = connect_to_database(connection_string)

    def disconnect(self):
        if hasattr(self, 'connection'):
            delattr(self, 'connection')
            print("Database connection closed.")

conn = DatabaseConnection("my_db_connection_string")
conn.disconnect()

这里 ,disconnect 方法使用 hasattr 检查 connection 属性是否存在,存在则使用 delattr 删除之,模拟了数据库连接的关闭过程。

4.3 警惕:删除属性的副作用

虽然 delattr 提供了强大的动态属性管理能力,但使用时也需格外小心。删除一个对象的关键属性可能会导致对象处于不一致状态 ,影响后续的正常操作。特别是对于那些依赖于特定属性存在的方法,删除这些属性可能会引发意外的错误。

另外,尝试删除一个不可删除的属性(如某些内置类型或第三方库中的属性)会导致 AttributeError。此外,对于静态属性(类变量)的删除,应当使用 del 关键字直接在类定义外部操作,而不是 delattr

总之,在使用 delattr 时 ,务必清楚其潜在的副作用,并确保有充分的理由去执行属性删除操作,以免引入难以预料的错误到你的代码中。

5、综合案例:构建动态属性处理器 🌀

5.1 设计思路解析

在面向对象编程中,动态属性处理器是一种能够根据运行时数据动态创建、修改、检查或删除对象属性的机制。这种能力在处理高度可定制或不确定的业务逻辑时尤为关键 ,比如配置管理、元编程等场景。我们将利用getattrsetattrhasattrdelattr构建一个简单的动态属性处理器 ,以展示其在实际应用中的灵活性和效率。

功能目标:
  1. 根据传入的键值对动态创建对象属性。

  2. 提供方法检查对象是否具有特定属性。

  3. 允许安全地修改对象属性。

  4. 支持按需删除对象属性。

设计步骤:
  1. 初始化对象:创建一个基础类,用于存储和管理动态属性。

  2. 动态属性创建:实现方法接收键值对列表 ,使用setattr为对象动态添加属性。

  3. 属性检查:设计函数,利用hasattr检查对象是否具有给定的属性名。

  4. 属性修改:提供接口,通过setattr安全地修改现有属性值。

  5. 属性删除:实现功能 ,使用delattr按需移除属性。

5.2 代码实现与优化

接下来,我们将按照上述设计思路,逐步实现一个动态属性处理器的代码框架。

示例代码:

class DynamicAttrHandler:
    def __init__(self):
        # 初始化,对象默认无任何动态属性
        pass

    def add_attributes(self, attributes):
        """
        根据传入的键值对列表 ,动态创建对象属性。
        :param attributes: 键值对列表 ,如 [('name', 'Alice'), ('age', 30)]
        """
        for key, value in attributes:
            setattr(self, key, value)

    def has_attribute(self, attribute_name):
        """
        检查对象是否具有特定属性。
        :param attribute_name: 待检查的属性名
        :return: True/False
        """
        return hasattr(self, attribute_name)

    def set_attribute(self, attribute_name, value):
        """
        安全地修改现有属性值。
        :param attribute_name: 属性名
        :param value: 新的属性值
        """
        setattr(self, attribute_name, value)

    def delete_attribute(self, attribute_name):
        """
        移除对象的指定属性。
        :param attribute_name: 要删除的属性名
        """
        if self.has_attribute(attribute_name):
            delattr(self, attribute_name)

# 实例化动态属性处理器
handler = DynamicAttrHandler()

# 动态添加属性
handler.add_attributes([('name', 'Alice'), ('age', 30)])

# 检查属性是否存在
print(handler.has_attribute('name'))  # 应输出True
print(handler.has_attribute('gender'))  # 应输出False

# 修改属性值
handler.set_attribute('age', 31)

# 删除属性
handler.delete_attribute('age')

# 最终状态验证
print(handler.__dict__)

输出:

True
False
{'name': 'Alice'}

在上述代码中 ,我们定义了一个DynamicAttrHandler类 ,它封装了动态属性的创建、检查、修改和删除功能。通过一系列方法的组合使用 ,我们构建了一个能够灵活响应运行时数据变化的动态属性处理器,这在实际项目中具有广泛的应用前景,尤其是在需要高度定制化或动态配置的系统中。

6、深入Python数据模型 📖

6.1 揭秘__getattribute__

在Python中,__getattribute__是一个特殊方法 ,它定义了对象属性的获取方式。当尝试访问对象的属性时,Python解释器会调用这个方法,而不是直接访问属性。这为自定义属性的获取流程提供了极大的灵活性,使得开发者可以添加额外的逻辑 ,如属性的验证、转换或动态生成等。

示例代码:

class CustomObject:
    def __init__(self, value):
        self._value = value

    def __getattribute__(self, item):
        if item == '_value':
            return 'Access to _value is restricted!'
        else:
            return super().__getattribute__(item)

obj = CustomObject(42)

print(obj._value)  # 将调用__getattribute__
print(obj.__dict__)  # 直接访问对象字典,绕过__getattribute__

输出:

Access to _value is restricted!
{'_value': 42}

在这个例子中,CustomObject类重写了__getattribute__方法,限制了对_value属性的直接访问,而允许通过对象字典__dict__间接访问。这展示了如何利用__getattribute__来控制属性的访问逻辑。

6.2 自定义属性访问控制

除了__getattribute__,Python还提供了__getattr____setattr__等特殊方法,分别用于处理未定义属性的访问和属性的设置。这些方法的结合使用,可以实现更复杂的属性访问控制机制。

示例代码:

class DynamicProperty:
    def __init__(self):
        self._properties = {}

    def __getattr__(self, item):
        if item in self._properties:
            return self._properties[item]
        else:
            raise AttributeError(f"'{self.__class__.__name__}' object has no attribute '{item}'")

    def __setattr__(self, key, value):
        if key.startswith('_'):
            super().__setattr__(key, value)
        else:
            self._properties[key] = value

dp = DynamicProperty()
dp.name = 'Alice'
dp.age = 30

print(dp.name)
print(dp.age)

try:
    print(dp.gender)
except AttributeError as e:
    print(e)

输出:

Alice
30
'DynamicProperty' object has no attribute 'gender'

这段代码定义了一个DynamicProperty类,它使用__getattr____setattr__实现了动态属性的存储和访问。当尝试设置或获取属性时,这些方法会被调用 ,从而实现了对属性的动态管理。如果尝试访问一个未定义的属性,__getattr__会抛出AttributeError,确保了属性访问的健壮性。

7、性能考量与最佳实践 ⏱️

7.1 动态属性操作的性能影响

在Python中频繁使用 getattrsetattrhasattrdelattr 这类动态属性访问函数可能会对性能产生一定影响。每次调用这些函数时,Python解释器都需要进行额外的查找和安全性检查,相比于直接访问属性(即通过.属性名方式) ,这会带来微小的性能开销。在大规模循环或高频率调用的场景下,这种开销可能会累积 ,进而影响整体性能。

7.2 优化策略:减少动态属性依赖

为了提高效率,可以采取以下策略减少对动态属性操作的依赖:

  1. 属性缓存:如果属性访问模式相对固定 ,可以考虑首次访问时缓存属性引用 ,后续直接使用缓存的引用访问属性,避免重复的查找过程。

示例代码:

class CachedAccess:
    def __init__(self):
        self._cached_attr = None

    def cached_get(self, obj, attr_name):
        if self._cached_attr is None:
            self._cached_attr = getattr(obj, attr_name)
        return self._cached_attr
  1. 直接访问:在可能的情况下,优先使用直接属性访问,特别是在循环和关键路径代码中。对于那些确定性的属性,直接使用点操作符(.)访问会更高效。

  2. 设计模式优化:采用如“策略模式”、“装饰器模式”等设计模式重构代码,减少对动态属性操作的直接依赖,转而通过更高效的设计模式来组织和管理属性。

7.3 实战建议:平衡灵活性与效率

在实际应用中 ,平衡动态属性带来的灵活性与潜在的性能损失至关重要。以下是一些建议:

  • 评估使用场景:仔细分析应用的具体需求,识别哪些部分对性能敏感 ,哪些部分需要高度灵活性。对性能敏感的部分尽量减少动态属性的使用。

  • 分层设计:在架构设计上,可以将需要高度动态性的部分与性能敏感部分分开 ,使动态属性操作的影响局部化。

  • 适时使用反射:在需要高度灵活性或动态性配置的场景(如插件系统、动态配置加载)中,适时利用反射机制是合理的,但应确保对性能影响的监控和优化。

  • 性能测试:在引入动态属性操作后,通过性能测试工具(如Python的timeit模块或第三方库如pytest-benchmark)定期评估关键路径的性能,确保优化措施的有效性。

通过上述策略和建议 ,开发者可以在享受动态属性带来的便利的同时,有效控制和优化性能,达到灵活性与效率的和谐共存。

8、总结与展望 🚀

探索Python中getattrsetattrhasattr, 和 delattr的使用之旅,揭示了动态属性操作的精髓。从基础应用到高级技巧,这些函数不仅助力于对象属性的灵活获取与修改 ,还确保了安全性与内存管理的高效性。通过实战演练,如构建动态属性处理器,深入理解其在设计模式及实际项目中的强大功能。对比Java反射机制与JavaScript的相似功能,凸显了Python在动态语言特性上的独特优势。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1908377.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

零基础也能成为产品册设计高手

​在当今数字化时代,产品册设计已成为企业营销的重要手段之一。过去,人们认为只有专业人士才能设计出精美的产品册,然而,随着设计工具的普及和在线学习资源的丰富,零基础的你也能成为产品册设计高手。本文将带你走进这…

一文清晰了解HTML

有这样一个txt记事本文件和一张图片&#xff1a; txt文本内容是这样的&#xff1a; <html><head><title>HTML学习</title></head><body><h1>hello HTML</h1><img src"高清修复.png"/></body> </html…

泫雅甜蜜官宣爱情开花

【标题】泫雅甜蜜官宣&#xff1a;爱情花开&#xff0c;携手龙俊亨共赴婚姻殿堂&#xff0c;邀您共鉴幸福时刻&#xff01;在这个金秋送爽、爱意弥漫的季节里&#xff0c;韩国娱乐圈迎来了一则振奋的消息——我们的“小野马”泫雅&#xff0c;正式宣布了她人生中的重大决定&…

MyBatis是如何分页的及原理

MyBatis 是一种持久层框架&#xff0c;支持通过配置文件和注解将 SQL 映射为 Java 对象。在实际开发中&#xff0c;查询数据时经常需要进行分页处理。 MyBatis 也提供了支持分页的方案&#xff0c;其主要思路是使用 Limit 偏移量和限制个数&#xff0c;来获取指定数量的数据。下…

全网视频下载之IDM下载安装,软破解

全网视频下载之IDM下载安装&#xff0c;软破解 介绍![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/c94f612f7a8845c8a649f74f6b18fd70.png)下载安装配置浏览器Google浏览器Ddge浏览器 界面如何下载不破解如何重复使用总结 介绍 今天给大家分享一个更加简便的全网视…

【Python】已解决:FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;FileNotFoundError: [Errno 2] No such file or directory: ‘D:\1. PDF’ 一、分析问题背景 在Python编程中&#xff0c;当你尝试打开一个不存在的文件时&…

放大镜案例

放大镜 <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>商品放大镜</title><link rel&qu…

【C语言】五子棋(c语言实现)

这里写目录标题 最终效果菜单打印函数棋盘的初始化和打印人人对战落子判空函数悔棋函数判胜负函数人人对战 人机对战一是将直接调用rand生成随机值&#xff0c;这就不可控二是根据棋子赢面来判断哪里落子最好 如果选择退出程序直接exit就行主函数调用逻辑源代码 最终效果 五子棋…

电脑显示x3daudio1_7.dll丢失如何修复,总结5种靠谱的修复方法

在使用电脑时&#xff0c;若系统提示x3daudio1_7.dll文件丢失&#xff0c;需及时进行修复操作&#xff0c;当此文件丢失或损坏时&#xff0c;人们可能会遇到一些音频功能方面的问题&#xff0c;如软件游戏无法正常启动运行。以下提供一种快速有效的修复方法。 一、了解x3daudio…

Flutter 是如何实现的 ?

Flutter 是由 Google 开发的一个开源 UI 软件开发工具包&#xff0c;用于构建跨平台的应用程序。Flutter 的核心理念是提供一个高度可定制、快速和现代的 UI 框架&#xff0c;它允许开发者使用一套代码库构建 Android、iOS、Web 和桌面应用程序。以下是 Flutter 的一些关键实现…

四川赤橙宏海商务信息咨询有限公司专业电商服务团队

在数字经济迅猛发展的今天&#xff0c;抖音电商以其独特的魅力和强大的市场潜力&#xff0c;成为了众多企业竞相追逐的蓝海。作为深耕抖音电商领域的专业服务商&#xff0c;四川赤橙宏海商务信息咨询有限公司凭借其丰富的经验和专业的团队&#xff0c;为众多商家提供了全方位、…

大模型应用元年,到底有哪些场景可以实际落地场景?

很多企业和个人都号称自己打造了AI大模型实际落地场景&#xff0c;其中有噱头、蹭热点&#xff0c;也有真实落地应用的。下面我将聊聊有哪些应用是真实落地可执行的。 大模型写作 生成式大语言大模型的看家本领非写作莫属。大模型输出logits的基础上加上top_p、top_k、temper…

spring boot集成easypoi导出word换行处理

项目场景&#xff1a; spring boot集成easypoi导出word <dependency><groupId>cn.afterturn</groupId><artifactId>easypoi-spring-boot-starter</artifactId><version>4.4.0</version> </dependency> 问题描述 spring boo…

java中Request和Response的详细介绍

1.Request和Response的概述 # 重点 1. service方法的两个参数request和response是由tomcat创建的void service(ServletRequest var1, ServletResponse var2) 2. request 表示请求数据, tomcat将浏览器发送过来的请求数据解析并封装到request对象中servlet开发者可以通过reques…

Studying-代码随想录训练营day31| 56.合并区间、738.单调递增的数字、968.监控二叉树、贪心算法总结

第31天&#xff0c;贪心最后一节(ง •_•)ง&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 56.合并区间 738.单调递增的数字 968.监控二叉树 贪心算法总结 56.合并区间 文档讲解&#xff1a;代码随想录合并区间 视频讲解&#xff1a;手撕合并区间 题目&#xf…

美妆网页设计(前端)

目录 一、 网站背景&#xff1a; 1、 背景介绍 2、 项目意义 二、 系统设计&#xff1a; 1.系统目标 2.系统功能结构 3.开发环境 三、 开发实现 1、导航栏 2、轮播效果效果 3、下拉菜单效果 4、模态框 遇到的问题及解决办法 五、 总结&#xff1a; 网站背景&…

【LabVIEW学习篇 - 5】:数据类型——数值、字符串

文章目录 数值枚举下拉列表控件 字符串字符串与十六进制截取字符串连接字符串 字符串与数值间的转换字符串转为数值数值转为字符串 数值 如下图所示&#xff0c;各种数值型数据的不同之处在于存储和表示数据时所使用的位置不同。 浮点型 整型 在LabVIEW中&#xff0c;想要改…

Android计算器界面的设计——表格布局TableLayout实操

目录 任务目标任务分析任务实施 任务目标 使用TextView、Button等实现一个计算器界面&#xff0c;界面如图1所示。 图1 计算器界面效果图 任务分析 界面整体使用表格布局&#xff0c;第一行使用一个TextView控件&#xff0c;横跨4列&#xff0c;中间4行4列&#xff0c;最后一…

Mysql笔记-v2

零、 help、\h、? 调出帮助 mysql> \hFor information about MySQL products and services, visit:http://www.mysql.com/ For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Enterprise support, training, …

EAI四个层次服务-系统架构师(二十六)

1、&#xff08;重点&#xff09;系统应用集成提供了4个不同层次服务&#xff0c;最上层服务是&#xff08;&#xff09;服务。 解析: EAI&#xff08;Enterprise Application Integration&#xff09;系统应用集成&#xff0c;相关概念。 实施EAI必须保证&#xff1a;应用程…