31天Python入门——第19天:再学面向对象·一切皆对象

发布于:2025-04-02 ⋅ 阅读:(22) ⋅ 点赞:(0)

在这里插入图片描述

你好,我是安然无虞。


在这里插入图片描述

1. 静态方法和类方法

静态方法

在 Python 中,静态方法(Static Method)是属于类的方法而不是属于实例的方法.

它们与类的实例无关,因此在调用静态方法时,不需要传入实例(self)作为参数.

静态方法是通过 @staticmethod 装饰器来声明的.

class A:
  
  @staticmethod
  def print_info(xxx):
    print(xxx)
    
a = A()
# 静态方法让一个函数从属于一个类了
A.print_info("这是一个示例")
a.print_info("这是一个示例")

# 从上面可以看出:
# 静态方法可以直接通过类名调用, 也可以通过实例调用

静态方法有以下特点:

  1. 不需要实例化对象:静态方法不依赖于类的实例,因此可以直接通过类名来调用,而不需要创建类的实例.
  2. 不需要 self 参数:静态方法不会自动传递实例(self)作为参数,它的参数列表中只包含定义在方法中的参数.
  3. 不能访问实例属性和实例方法:由于静态方法不与实例相关联,因此它不能直接访问实例的属性和实例方法.
  4. 静态方法可以直接通过类名调用, 也可以通过实例调用.

静态方法通常用于执行与类相关的任务,但不依赖于类的实例状态或属性的操作.

例如,可以将静态方法用于辅助函数、工具函数或者用于创建对象的辅助方法等。

class Date:

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return f"{self.year}/{self.month}/{self.day}"

    @staticmethod
    def create_instance_from_string(_date_string):
        _date_list = _date_string.split('-')
        obj = Date(int(_date_list[0]), int(_date_list[1]), int(_date_list[2]))
        return obj


if __name__ == '__main__':
    date_string = '2025-03-27'
    date = Date.create_instance_from_string(date_string)
    print(date)

类方法

在 Python 中,类方法(Class Method)是一种特殊类型的方法,它属于类而不是属于实例。类方法使用 @classmethod 装饰器来声明,并且第一个参数通常被命名为 cls,表示类本身,而不是实例。

类方法具有以下特点:

  1. 第一个参数是类本身:类方法的第一个参数通常被命名为 cls,表示类本身. 通过这个参数,类方法可以访问和修改类级别的属性和方法.
  2. 可以通过类名或实例调用:类方法可以通过类名来调用,也可以通过类的实例来调用. 在调用时,不需要传入实例(self)作为参数.
  3. 可以访问类级别的属性和方法:由于类方法的第一个参数是类本身,因此它可以访问和修改类级别的属性和方法.

类方法通常用于执行与类相关的操作,而不需要依赖于类的实例. 常见的用途包括创建类的实例的辅助方法,或者在类级别上管理类的状态.

class A:

    var = 3

    def __init__(self):
        self.xx = 6

    @classmethod
    def print_info(cls):
        cls.var = 5
        print(cls.var)

    def print_ins(self):
        print(self)

a = A()
a.print_ins()
A.print_info()
a.print_info()

# <__main__.A object at 0x7fb76000ae20>
# 5
# 5
# 我们可以改写前面的Date静态方法为类方法
# 这里使用类方法的好处是: 当类名有改动, 类方法中涉及到类名的地方不需要改, 因为类方法可以直接使用cls代替类名.
class Date:

    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return f"{self.year}/{self.month}/{self.day}"

    @classmethod
    def create_instance_from_string(cls, _date_string):
        _date_list = _date_string.split('-')
        obj = cls(int(_date_list[0]), int(_date_list[1]), int(_date_list[2]))
        return obj


if __name__ == '__main__':
    date_string = '2025-03-27'
    date = Date.create_instance_from_string(date_string)
    print(date)

2. property

在 Python 中,@property 是一个装饰器,它用于将方法转换为只读属性.

使用 @property 装饰器可以使类的接口更加简洁,同时提供一种对属性进行控制和校验的方式.

使用@property装饰过后的方法会被当做属性处理, 是不可调用的.

class A:

    @property
    def value(self):
        return 3

    def get_value(self):
        print(f"value的值是: {self.value}")

a = A()
a.get_value() # 3

print(a.value()) # 报错: TypeError: 'int' object is not callable

同时@property装饰器还可以与其他装饰器一起使用,以实现更多的功能. 其中,最常用的是 @property@<property_name>.setter 装饰器的组合,用于定义属性的设置方法.

class A:
  
  def __init__(self):
    self.__value = 10
    
  @property
  def value(self):
    return self.__value
  
  @value.setter
  def value(self, value):
    self.__value = value
    
a = A()
a.value = 6
print(a.value) # 6

property还可以用作动态属性.

from datetime import datetime
 
class Date:
 
 @property
 def now(self):
   return datetime.now()
 
 def print_now(self):
   print(f"现在的时间是{self.now}")

3. getattr 和 setattr

getattrsetattr 是 Python 内置函数,用于动态地获取和设置对象的属性. 它们提供了一种在运行时操作对象属性的方式.

getattr

 getattr(object, name[, default])

参数说明

  • object: 表示要获取属性的对象.
  • name: 表示要获取的属性名.
  • default (可选): 表示在属性不存在时返回的默认值,默认为 None.

返回值

  • 如果对象拥有指定的属性,返回该属性的值.
  • 如果对象没有指定的属性,并且提供了 default 参数,则返回 default 参数的值.
  • 如果对象没有指定的属性,并且没有提供 default 参数,则会抛出 AttributeError 异常.

setattr

 setattr(object, name, value)

参数说明

  • object: 表示要设置属性的对象.
  • name: 表示要设置的属性名.
  • value: 表示要设置的属性值.

返回值

setattr 函数没有返回值.

4. isinstance和type

isinstancetype 是 Python 内置函数,用于判断对象的类型。它们在编程中常用于类型检查,帮助我们判断一个对象是否属于某个特定的类型。

 isinstance(object, classinfo)

参数说明

  • object: 表示要检查类型的对象。
  • classinfo: 表示要比较的类型,可以是类型对象或类型元组。

返回值

  • 如果 objectclassinfo 类型(或是 classinfo 元组中的任何一种类型),则返回 True
  • 否则,返回 False

type

 type(object)

object: 表示要获取类型的对象。

print(isinstance(5, int))
print(isinstance("hello", str))
print(isinstance(True, bool))

print(type('a'))
print(type(5))
print(type(True))

5. Python中一切皆对象

在 Python 中,“一切皆对象”是一种重要的编程思想. 它将数据、函数、模块、类和实例统一视为对象,赋予了 Python 强大的灵活性和可扩展性. 理解并熟练运用对象的概念,有助于编写出更加清晰、模块化和易于维护的 Python 代码. 同时,它也为进一步深入学习 Python 的高级特性和编程范式奠定了基础.

在 Python 中,对象是内存中的数据块,每个对象都有唯一的标识符、类型和值. 例如,整数、字符串、列表、字典等都是对象. 我们可以通过内置函数 id() 获取对象的标识符,type() 获取对象的类型. 函数和模块也是对象. 我们可以像操作其他对象一样对函数和模块进行操作. 函数可以赋值给变量、作为参数传递给其他函数、作为返回值返回等. 类也是对象. 我们可以用类创建实例,实例也是对象. 类是对象的模板,实例是根据类创建的具体对象. 类可以拥有属性和方法,实例可以调用类的方法和访问属性.

a = 1
print(type(a)) # <class 'int'>
print(type(int)) # <class 'type'>
# 所以 type -> int -> 1

b = 'string'
print(type(b)) # <class 'str'>
print(type(str)) # <class 'type'>
# 所以 type -> str -> 'string'

通过上面的验证, 我们发现:

type -> class -> instance
type产生类, 类产生实例.

class A:
    pass


a = A()
print(type(a)) # <class '__main__.A'>
print(type(A)) # <class 'type'>

可能有老铁会问: 类的type是type, 那type的type是什么呢?

print(type(type)) # <class 'type'>

由此我们发现, type也是它本身的实例.
所以在Python中, 无论是自定义类型还是内置类型, 都是type的实例.

因为所有的类都是继承object类, 如果你不写, 那么也是隐式的(默认的)去继承.

class A(object):
    pass
class A():
    pass


# 查看父类
print(A.__base__) # <class 'object'>
print(int.__base__) # <class 'object'>
class A():
    pass


class B(A):
    pass


print(A.__base__) # <class 'object'>
print(int.__base__) # <class 'object'>
print(B.__base__) # <class '__main__.A'>

由此可见, Python中所有的类, 最终都是继承object, 所以object类是所有类的基类.

print(type.__base__) # <class 'object'>

type的基类也是object类

print(type(object)) # <class 'type'>

object类也是type的实例, 毕竟type是其本身的实例.

def xxx():
    a = 1
    return a


code = xxx.__code__
print(xxx.__code__)
print(dir(code))

在这里插入图片描述

  • 虚线代表实例
  • 实线代表继承
遇见安然遇见你,不负代码不负卿。
谢谢老铁的时间,咱们下篇再见~

网站公告

今日签到

点亮在社区的每一天
去签到