首页 > 其他分享 >类特殊成员(属性与方法)

类特殊成员(属性与方法)

时间:2023-12-13 18:11:07浏览次数:30  
标签:__ 特殊 name 对象 成员 class print self 属性

目录

1. setattr()、getattr()、hasattr()

setattr()getattr()hasattr() 是 Python 中用于处理对象属性的三个内建函数。

setattr()

setattr() 函数用于设置对象的属性值。其基本语法为:

setattr(object, attribute, value)
  • object 是要设置属性的对象。
  • attribute 是属性的名称。
  • value 是要设置的属性值。
class Person:
    pass

# 创建 Person 类的实例
person_instance = Person()

# 设置实例的属性值
setattr(person_instance, 'name', 'Alice')
setattr(person_instance, 'age', 25)

print(person_instance.name)  # 输出: Alice
print(person_instance.age)   # 输出: 25

getattr()

getattr() 函数用于获取对象的属性值。其基本语法为:

getattr(object, attribute[, default])
  • object 是要获取属性的对象。
  • attribute 是属性的名称。
  • default 是可选参数,用于指定在属性不存在时的默认值。
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
# 创建 Person 类的实例
person_instance = Person(name='Alice', age=25)

# 获取实例的属性值
name_value = getattr(person_instance, 'name')
age_value = getattr(person_instance, 'age')

print(name_value)  # 输出: Alice
print(age_value)   # 输出: 25

# 获取不存在的属性,提供默认值
gender_value = getattr(person_instance, 'gender', 'Unknown')
print(gender_value)  # 输出: Unknown

hasattr()

hasattr() 函数用于检查对象是否具有指定的属性。其基本语法为:

hasattr(object, attribute)
  • object 是要检查属性的对象。
  • attribute 是要检查的属性名称。
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

# 创建 Person 类的实例
person_instance = Person(name='Alice', age=25)

# 检查实例是否具有指定的属性
has_name = hasattr(person_instance, 'name')
has_gender = hasattr(person_instance, 'gender')

print(has_name)    # 输出: True
print(has_gender)  # 输出: False

这三个函数通常用于动态地操作对象的属性,特别是当属性的名称是在运行时确定的情况下。

2. init():初始化对象的实例

__init__() 是 Python 类中的一个特殊方法,用于初始化对象的实例。它是一个构造方法(constructor),在创建类的实例时自动被调用。__init__() 方法允许你在创建对象时执行一些必要的设置或初始化工作。

以下是 __init__() 方法的基本用法:

class MyClass:
    def __init__(self, parameter1, parameter2, ...):
        # 在这里进行初始化工作
        self.attribute1 = parameter1
        self.attribute2 = parameter2
        # ...

# 创建类的实例
my_instance = MyClass(value1, value2, ...)

示例:

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

# 创建 Person 类的实例
person_instance = Person("Alice", 25)

# 访问实例属性
print(person_instance.name)  # 输出: Alice
print(person_instance.age)   # 输出: 25

在这个例子中,__init__() 方法用于初始化 Person 类的实例,分别设置了 nameage 属性。

3. new():init()能力补充

new() 是一种负责创建类实例的静态方法,它无需使用 staticmethod 装饰器修饰,且该方法会优先 init() 初始化方法被调用。

那么,什么情况下使用 new() 呢?答案很简单,在 init() 不够用的时候。

例如,前面例子中对 Python 不可变的内置类型(如 int、str、float 等)进行了子类化,这是因为一旦创建了这样不可变的对象实例,就无法在 init() 方法中对其进行修改。

有些读者可能会认为,new() 对执行重要的对象初始化很有用,如果用户忘记使用 super(),可能会漏掉这一初始化。虽然这听上去很合理,但有一个主要的缺点,即如果使用这样的方法,那么即便初始化过程已经是预期的行为,程序员明确跳过初始化步骤也会变得更加困难。不仅如此,它还破坏了“init() 中执行所有初始化工作”的潜规则。

注意,由于 new() 不限于返回同一个类的实例,所以很容易被滥用,不负责任地使用这种方法可能会对代码有害,所以要谨慎使用。一般来说,对于特定问题,最好搜索其他可用的解决方案,最好不要影响对象的创建过程,使其违背程序员的预期。比如说,前面提到的覆写不可变类型初始化的例子,完全可以用工厂方法(一种设计模式)来替代。

4. repr():输出对象内部信息

我们经常会直接输出类的实例化对象,例如:

class CLanguage:    
    pass
clangs = CLanguage()
print(clangs)

程序运行结果为:

<__main__.CLanguage object at 0x000001A7275221D0>

通常情况下,直接输出某个实例化对象,本意往往是想了解该对象的基本信息,例如该对象有哪些属性,它们的值各是多少等等。但默认情况下,我们得到的信息只会是“类名+object at+内存地址”,对我们了解该实例化对象帮助不大。

那么,有没有可能自定义输出实例化对象时的信息呢?答案是肯定,通过重写类的 repr() 方法即可。事实上,当我们输出某个实例化对象时,其调用的就是该对象的 repr() 方法,输出的是该方法的返回值。

通过在类中重写这个方法,从而实现当输出实例化对象时,输出我们想要的信息。

案例配置:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Point(x={self.x}, y={self.y})"

# 创建 Point 类的实例
point = Point(1, 2)

# 使用 repr() 函数获取对象的字符串表示
repr_str = repr(point)
print(repr_str)  # 输出: Point(x=1, y=2)

# 直接打印对象,会调用对象的 __repr__() 方法
print(point)     # 输出: Point(x=1, y=2)

上面案例通过__repr__输出对象中属性的一些信息,可以利用这些数值返回了解数据的信息。

5. str():输出提示信息

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f"Point at ({self.x}, {self.y})"

# 创建两个 Point 类的实例
point1 = Point(3, 5)
point2 = Point(7, 10)

# 调用 __str__() 方法
str_representation1 = str(point1)
str_representation2 = str(point2)

# 直接使用 print() 函数,会自动调用 __str__() 方法
print(point1)  # 输出: Point at (3, 5)
print(point2)  # 输出: Point at (7, 10)

# 使用 f-string 输出字符串表示
print(f"The first point is {point1}.")  # 输出: The first point is Point at (3, 5).
print(f"The second point is {point2}.")  # 输出: The second point is Point at (7, 10).

__str__ 方法的目的是为了在使用 print() 函数时提供一个友好、人类可读的字符串表示形式。如果没有定义 __str__ 方法,那么 print() 函数会调用对象的 __repr__ 方法,或者使用默认的输出方式。

6. issubclass和isinstance函数

  • issubclass(cls, class_or_tuple):检查 cls 是否为后一个类或元组包含的多个类中任意类的子类。
  • isinstance(obj, class_or_tuple):检查 obj 是否为后一个类或元组包含的多个类中任意类的对象。

issubclass 的应用场景

(1)检查继承关系: 在编写框架或库时,可以使用 issubclass 来检查一个类是否是某个基类的子类,以确保符合预期的继承关系。

class Shape:
    pass

class Circle(Shape):
    pass

# 在某个函数中检查是否是 Shape 的子类
def process_shape(shape_class):
    if issubclass(shape_class, Shape):
        # 处理 Shape 类或其子类的逻辑
        pass

(2)动态选择实现: 在某些情况下,根据对象的类型来选择不同的实现。issubclass 可以帮助你动态选择适当的类。

class Shape:
    def draw(self):
        raise NotImplementedError

class Circle(Shape):
    def draw(self):
        print("Drawing a circle")

class Square(Shape):
    def draw(self):
        print("Drawing a square")

def draw_shape(shape):
    if issubclass(type(shape), Shape):
        shape.draw()

isinstance 的应用场景

(1)类型检查: 在函数中对传入的参数进行类型检查,确保参数是预期的类或类型。

def process_data(data):
    if isinstance(data, (list, tuple)):
        # 处理列表或元组的逻辑
        pass

(2)多态实现: 允许对象根据其类型表现出不同的行为。这在设计模式中的多态概念中经常用到。

class Animal:
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        print("Woof!")

class Cat(Animal):
    def make_sound(self):
        print("Meow!")

def animal_sound(animal_instance):
    if isinstance(animal_instance, Animal):
        animal_instance.make_sound()

(3)处理不同版本或类型的对象: 在处理对象集合时,可以使用 isinstance 来过滤或处理不同版本或类型的对象。

class Version1:
    pass

class Version2:
    pass

objects = [Version1(), Version2()]

for obj in objects:
    if isinstance(obj, Version1):
        # 处理 Version1 类型的对象
        pass
    elif isinstance(obj, Version2):
        # 处理 Version2 类型的对象
        pass

总体来说,这两个函数在处理多态性、动态类型和对象关系时非常有用。在编写灵活且可扩展的代码时,它们可以帮助你进行更动态的类型检查。

7. 生成器:按需生成值非一次性保存在内存

生成器(Generator)是 Python 中用于生成迭代器的一种特殊类型的对象。它允许你按需生成一系列值,而不是一次性生成并保存在内存中。生成器使用 yield 语句来产生值,而不是使用 return

def fibonacci_generator(n):
    a, b = 0, 1
    count = 0
    while count < n:
        yield a
        a, b = b, a + b
        count += 1

# 使用生成器获取斐波那契数列的前10个数字
fibonacci_gen = fibonacci_generator(10)

for number in fibonacci_gen:
    print(number)

结果输出:

0
1
1
2
3
5
8
13
21
34

yield 语句的特性是会在暂停时保存整个生成器的状态,包括所有的局部变量的值。在下一次调用生成器时,它会从上一次 yield 语句的位置开始执行,并且所有的局部变量都会恢复到上一次暂停时的状态。

具体到这个斐波那契数列的例子,当执行到 yield a 时,生成器会返回当前的 a 值,然后暂停。在暂停时,ab 的值会被保存,下一次调用生成器时,它会从上一次暂停的地方继续执行,而此时 ab 的值是上一次暂停时的值。

所以,yield 语句不仅返回一个值,而且它会保存整个生成器的状态,包括所有的局部变量。这就是为什么在下一次调用时,ab 的值会正确更新的原因。这种机制使得生成器可以在迭代过程中保持状态,而不是一次性生成所有的值。

标签:__,特殊,name,对象,成员,class,print,self,属性
From: https://www.cnblogs.com/NGU-PX/p/17899655.html

相关文章

  • 将第2层数据中的数组对象中的ts属性、value属性遍历单独存放到一个新数组中xData、yDa
          ......
  • C++类的静态成员
    C++类的静态成员声明并使用静态成员使用static关键字将其与类关联在一块,同样,static声明的对象也可以声明访问权限public,private注意,类的静态成员存在于任何对象之外,对象中不包含任何与静态数据有关的数据,就是说类中声明的静态成员是独立于类而存在的,只是和类相关联(这里的独立并不......
  • 通过PowerShellPlus示例脚本学习PowerShell之-输出SQLServer服务属性
    ##=====================================================================##Title:Get-MSSQL-ServerAttrib-Csv##Description:ConnecttoSQLServerandoutputserverattributestoCSV##Author:Idera##Date:1/28/2009##Input......
  • WPF 解决PasswordBox 属性Password无法绑定到后台的问题
    在WPF中,你可以使用密码框的Password属性来绑定到后台,但是由于安全性考虑,WPF的密码框不直接支持双向绑定。然而,你仍然可以通过其他方式实现将密码框的内容绑定到后台。一种常见的方法是创建一个附加属性(AttachedProperty)来实现密码框的双向绑定。以下是一个简单的示例代码:c......
  • 在C++中,预处理器提供了一些符号和运算符,这些符号在宏定义中有特殊的含义
    在C++中,预处理器提供了一些符号和运算符,这些符号在宏定义中有特殊的含义。以下是一些常见的符号:#:字符串化运算符,用于将宏参数转换为字符串。#defineSTRINGIZE(x)#xstd::cout<<STRINGIZE(Hello);//输出"Hello"##:连接运算符,用于连接两个标记,使它们成为一个标记。#de......
  • Flex 布局常用属性
    Flex布局(弹性布局)是CSS3中引入的一种布局模式,它通过display:flex;设置在容器上,然后利用一系列的属性来控制子元素的排列和对齐方式。以下是常用的Flex布局属性:displaydisplay:flex;:将容器指定为弹性容器。flex-directionflex-direction:row;:水平主轴,子元素水平排列(......
  • position 定位常用属性
    CSS的position属性用于指定元素的定位方式。以下是常见的position属性取值:position:static;默认值,元素按照正常的文档流布局显示,不进行特殊定位。position:relative;相对定位,元素相对于其正常位置进行定位。可以使用top、right、bottom、left属性来调整元素的位置。......
  • js 传参到 vue + 计算属性使用
    场景js中存储xAxisData=[......]、yAxisData=[......],想在vue中使用,但要求使用前转化成data存有若干个(x,y)的形式在改变xAxisData或yAxisData的任意一值时,都会反馈更新到vue的每一个调用了data的地方方法一:js中Cannotreadpropertiesofundefine......
  • 数据库的字段属性
    Unsigned:无符号的整数声明了该列不能声明为负数zerofill:0填充的不足的位数,使用0来填充,int(3),5---005自增:通常理解,自动在上一条记录的基础上+1(默认)通常用来设计唯一的主键~index,必须是整数类型可以自定义设计主键自增的起始值和步长非空null notnull假设设置为notnull,如果不......
  • Redis 3 种特殊数据类型详解、Redis内存碎片
    CacheAsidePattern(旁路缓存模式)CacheAsidePattern是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。CacheAsidePattern中服务端需要同时维系db和cache,并且是以db的结果为准。下面我们来看一下这个策略模式下的缓存读写步骤。写:先更新db然......