python基础(7)— 类

1、类定义

在Python中,类是一种用于创建对象的蓝图或模板。它定义了对象的属性和方法,并提供了创建该类对象的方法。类通常包括以下几个部分:

1. 类名:类的名称应该使用驼峰命名法(每个单词的首字母大写),以便与其他变量和函数进行区分。

2. 属性:属性是类的特征或数据。它们用于存储对象的状态。在类的定义中,可以声明属性并为其赋初值。

3. 方法:方法是定义在类中的函数。它们用于执行与类相关的操作。方法可以访问类的属性,并可以接受参数以执行特定的任务。

通过类和对象,我们可以组织和封装相关的数据和操作,使得程序更加模块化和可扩展。类的使用可以提高代码的可读性和可维护性,并支持面向对象编程的概念,如封装、继承和多态性。

2、创建类

在Python中,可以使用关键字`class`来定义一个类。类的名称通常以大写字母开头,遵循驼峰命名法(每个单词的首字母大写,没有下划线)。

下面是一个简单的Python类的定义示例:

class ClassName:
    pass

这个示例只是展示了创建一个最基本的类的方法,它没有任何属性或方法,你可以根据需要在这个最简单的类的基础上添加属性和方法。

3、类的属性(变量)

在Python中,类的属性和变量可以理解为同一概念的不同表述。用于存储对象的状态和数据的成员。类的属性特征如下:

  • 类的属性可以在类的任何位置进行定义,并且在类的任何方法中都可以使用。
  • 类的属性可以是各种数据类型,例如整数、浮点数、字符串等。
  • 类的属性可以通过点号操作符(.)访问和修改。

通常情况下,类的属性定义放在类的构造方法(`__init__`)中,通过`self`关键字将属性绑定到实例上。构造方法是在创建类的实例时自动调用的,可以用于初始化对象的属性。

除了构造方法,你还可以在类的其他方法中定义属性,或者在类的顶层直接赋值语句来定义属性。这些属性将成为类的类属性,即类的所有实例都共享相同的属性值。

1. 在构造方法中定义属性:

class MyClass:
    def __init__(self):
        self.property1 = value1
        self.property2 = value2

2. 在类的其他方法中定义属性:

class MyClass:
    def __init__(self):
        self.property1 = value1

    def method1(self):
        self.property2 = value2

3. 在类的顶层直接赋值语句定义属性:

class MyClass:
    property1 = value1
    property2 = value2

在这些示例中,`property1`和`property2`都是类的属性。它们可以在类的任何方法中使用,也可以通过类的实例进行访问。

以下是一个示例,展示了一个包含属性的类:

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

person = Person("Alice", 25)
print(person.name)  # 输出:Alice
print(person.age)  # 输出:25

在这个示例中,我们定义了一个名为`Person`的类,具有名为`name`和`age`的两个属性。构造方法`__init__`用于初始化对象的属性。在创建`Person`类的对象时,可以通过构造方法传递名字和年龄,并将它们赋值给相应的属性。然后,我们可以通过对象的属性名来访问属性的值。

4、类的方法

类的方法(Methods)是定义在类中的函数,用于执行特定的操作或实现特定的功能。类的方法可以访问类的属性,并且可以通过类的实例进行调用。

在Python中,类的方法可以分为以下几种类型:

1. 构造方法(Constructor):构造方法`__init__`,它在类的定义中使用`self`参数声明,并在创建类的实例时自动调用,用于初始化对象的初始状态。构造方法`__new__`,使用参数`cls`,在__init__方法之前调用,创建和返回一个新的对象。

2. 实例方法(Instance Methods):实例方法定义在类中,通过类的实例进行调用。实例方法在类的定义中使用`self`参数声明,可以访问和操作类的实例属性。实例方法通常用于执行与对象特定的操作,并且可以在方法内部调用其他实例方法。

3. 类方法(Class Methods):类方法使用`@classmethod`装饰器进行声明,用于操作类的属性和执行与类相关的操作。类方法在类的定义中使用`cls`参数表示对类自身的引用,可以访问类的属性,但不能直接访问实例属性。类方法通常用于实现与类相关的功能。

4. 静态方法(Static Methods):静态方法使用`@staticmethod`装饰器进行声明,与类和实例无关。静态方法不需要访问类的属性或实例属性,通常用于实现与类相关但不依赖于类状态的功能。静态方法可以在类的定义中直接声明,不需要`self`或`cls`参数。

5. `__call__`方法:`__call__`方法是一个特殊的方法,用于将类的实例作为函数调用。通过在类中定义`__call__`方法,可以使类的实例具备函数的行为,可以像函数一样被调用。

下面是一个示例,演示了这三种类型的类方法:

class MyClass:
    class_property = "Class Property"

    def __init__(self, instance_property):
        self.instance_property = instance_property

    def instance_method(self):
        print("Instance Method")
        print("Instance Property:", self.instance_property)

    @classmethod
    def class_method(cls):
        print("Class Method")
        print("Class Property:", cls.class_property)

    @staticmethod
    def static_method():
        print("Static Method")

在这个示例中,MyClass类包含一个实例属性instance_property和一个类属性class_property。它还定义了一个实例方法instance_method、一个类方法class_method和一个静态方法static_method。

5、类的实例化对象

1. 创建类的实例对象:使用类名后加括号的方式,调用类的构造方法,创建类的实例对象。

例如:

obj = MyClass("Alice")

在上面的示例中,我们创建了一个名为`obj`的`MyClass`类的实例对象。

2. 调用实例方法:使用实例对象的名称后跟点号(`.`)和实例方法的名称,即可调用该方法。

例如:

obj.say_hello()

在上面的示例中,我们使用`obj`对象实例调用了`say_hello`方法。

3. 访问属性:通过实例对象的名称后跟点号(`.`)和属性的名称,可以访问该属性的值。

例如:

print(obj.name)

在上面的示例中,我们通过`obj`对象实例访问了`name`属性的值。

请注意,每个实例对象都是独立的,它们有自己的属性值和方法,因此不同的对象实例调用相同的属性方法可能会产生不同的结果。

当我们定义一个类时,我们可以使用该类作为模板来创建多个对象,这些对象具有相同的属性和方法,但是它们是独立的实体。每个对象都可以独立地访问和修改其自己的属性,而不会影响其他对象。

下面是一个简单的示例,展示了如何实例化一个类对象:

class MyClass:
    def __init__(self, name):
        self.name = name
    
    def say_hello(self):
        print("Hello, " + self.name + "!")
        
# 实例化对象
obj1 = MyClass("Alice")
obj2 = MyClass("Bob")

# 调用对象的方法
obj1.say_hello()  # 输出: Hello, Alice!
obj2.say_hello()  # 输出: Hello, Bob!

在上面的示例中,我们定义了一个名为`MyClass`的类,其中包含一个构造方法`__init__`和一个实例方法`say_hello`。通过调用类名并传递参数,我们可以创建类的实例对象。在这个例子中,我们分别创建了`obj1`和`obj2`两个对象实例,并且通过调用对象的方法来输出不同的问候语。

每个对象实例都有自己的属性值,因此在调用方法时,可以根据对象的属性值产生不同的行为。类的实例化对象使我们能够以面向对象的方式组织和管理代码,将数据和相关操作封装在对象中。

6、__new__和__init__方法

`__new__`和`__init__`是Python中的两个特殊方法,用于创建和初始化对象。在类的创建过程中,首先会调用`__new__`方法创建对象实例,然后再调用`__init__`方法对对象进行初始化。

  • __new__方法用于创建对象实例,它在__init__方法之前被调用。第一个参数cls,表示对类自身的引用。
  • __init__方法用于初始化实例对象,在对象创建后被调用。第一个参数self,表示对当前对象的引用。

下面是一个示例:

class MyClass:
    def __new__(cls, *args, **kwargs):
        print("Creating instance")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("Initializing instance")
        self.name = name

obj = MyClass("example")

在上面的示例中,当我们创建`MyClass`的实例时,会先调用`__new__`方法创建实例,并打印"Creating instance"的消息。然后,调用`__init__`方法对实例进行初始化,并打印"Initializing instance"的消息。最终,我们得到一个具有`name`属性的`MyClass`实例。

7、方法的参数self和cls

`self`和`cls`是Python中用于表示对象和类的参数名称。

  • `self`是实例方法中的约定参数名,它表示对当前对象的引用。在定义实例方法时,第一个参数通常被命名为`self`,用于引用调用该方法的对象实例。通过`self`,我们可以在实例方法中访问和操作对象的属性和方法。
  • `cls`是类方法和静态方法中的约定参数名,它表示对类自身的引用。在定义类方法和静态方法时,第一个参数通常被命名为`cls`,用于引用类本身。通过`cls`,我们可以在类方法和静态方法中访问和操作类的属性和方法。

下面是一个示例,展示了`self`和`cls`的使用:

class MyClass:
    def instance_method(self):
        print("Instance method")
        print("self:", self)
    
    @classmethod
    def class_method(cls):
        print("Class method")
        print("cls:", cls)

obj = MyClass()
obj.instance_method()  # 调用实例方法
MyClass.class_method()  # 调用类方法

在上面的示例中,我们定义了一个名为`MyClass`的类,其中包含一个实例方法`instance_method`、一个类方法`class_method`。在实例方法中,我们使用`self`参数引用对象实例;在类方法中,我们使用`cls`参数引用类本身。

8、func和func()区别

`func`和`func()`的区别如下:

  • `func`是函数对象,它是函数本身的表示形式。可以将函数赋值给变量,传递给其他函数作为参数,或作为函数的返回值。可以通过变量名来引用函数对象。
  • `func()`是函数调用,它是执行函数并返回结果的操作形式。需要在函数名后加上括号,并根据需要传递参数。函数调用会执行函数内部的代码,并返回函数的返回值(如果有)。

总结起来,`func`是函数对象,而`func()`是函数调用。例如:

def func():
    return 1

print(func)    # <function func at 0x000001341AE10E50>
print(func())    # 1

代码中,func是一个函数对象,它引用了一个函数,该函数返回值为1。当你使用print(func)时,它会打印函数对象的信息,包括函数的名称和内存地址。而当你使用print(func())时,它会执行函数并打印函数的返回值,即1。

所以,print(func)会输出函数对象的信息,而print(func())会执行函数并输出返回值。

9、类名和py文件名要一致吗?

类名和Python文件名不一定要一致。在Python中,一个文件可以包含多个类定义,或者可以没有类定义。文件名只需要符合一些基本的命名规则,如使用小写字母、下划线和数字,以及以`.py`作为文件扩展名即可。

通常情况下,为了方便管理和维护代码,建议将每个类定义放在单独的文件中,并使用与类名相同的文件名。这样可以使代码更加清晰和易于理解,也符合一些代码组织的最佳实践。

然而,Python并不强制要求类名和文件名一致,你可以根据自己的需要和项目的规范来决定是否一致。重要的是在使用类时能够正确导入和引用相应的类定义。

10、命名空间和作用域

命名空间(Namespace)和作用域(Scope)是Python中用于管理变量和标识符的概念。

命名空间是一个存储变量和标识符名称的容器,用于区分不同的名称,并避免冲突。在Python中,命名空间可以是全局命名空间(Global Namespace)和局部命名空间(Local Namespace)。每个模块、函数和类都有自己的命名空间用于存储对应的变量和标识符。

作用域指的是在程序中访问和操作变量的有效范围。Python中有三种作用域:局部作用域(Local Scope)、嵌套作用域(Enclosing Scope)和全局作用域(Global Scope)。在函数内部定义的变量处于局部作用域,只能在函数内部访问。嵌套作用域指的是函数内部的函数,内部函数可以访问外部函数的变量。全局作用域指的是在模块层级定义的变量,可以在整个模块内访问。

Python按照以下规则查找变量和标识符:
1. 首先在当前作用域中查找变量。
2. 如果在当前作用域找不到,则在上一级嵌套作用域中查找,直到找到为止。
3. 如果在嵌套作用域中还找不到,则在全局作用域中查找。
4. 如果在全局作用域中还找不到,则会引发`NameError`错误。

需要注意的是,可以使用`global`和`nonlocal`关键字在局部作用域中访问和修改全局和嵌套作用域的变量。

总结起来,命名空间用于区分不同的名称,而作用域定义了变量的可见范围和访问规则。理解命名空间和作用域的概念对于正确理解和管理变量在Python程序中的行为非常重要。

详见:python基础 — 变量和作用域

11、一切皆对象

在Python中,一切皆对象意味着每个值都是一个对象,包括数字、字符串、函数、类和模块等。对象在Python中具有属性和方法,可以访问和操作这些属性和方法。

这个概念源于Python的面向对象编程特性。在面向对象编程中,程序由多个对象组成,每个对象都有自己的状态(属性)和行为(方法)。Python中的一切都被视为对象,这意味着你可以像操作其他对象一样来操作它们。

例如,你可以对整数对象执行算术运算,对字符串对象执行字符串操作,对函数对象调用函数,对类对象创建实例等等。每个对象都有自己的特性和功能,你可以通过调用对象的方法或访问其属性来使用这些功能。

这个概念的好处之一是,它使得Python非常灵活和可扩展。你可以通过创建自定义的类和对象来构建复杂的数据结构和功能,并通过继承和多态等面向对象的特性来组织和管理代码。

总之,"一切皆对象"是指在Python中,每个值都是一个对象,具有属性和方法,可以通过操作对象来完成各种任务。这个概念是Python语言设计的基础之一,也是理解Python编程范式的关键之一。

12、子类继承父类的构造方法

要让子类继承父类的构造方法,你可以在子类的`__init__`方法中使用`super()`函数调用父类的构造方法。这样子类就会继承父类的构造方法,并执行父类的初始化操作。

以下是一个示例,展示了子类如何继承父类的构造方法:

class ParentClass:
    def __init__(self, name):
        self.name = name

class ChildClass(ParentClass):
    def __init__(self, name, age):
        super().__init__(name)
        self.age = age

child = ChildClass("John", 10)
print(child.name)  # 输出: John
print(child.age)   # 输出: 10

在上面的例子中,`ParentClass`是父类,`ChildClass`是子类。子类`ChildClass`的`__init__`方法中使用`super().__init__(name)`调用了父类`ParentClass`的构造方法,并传递了必要的参数。这样子类就会继承父类的构造方法,同时可以添加自己特有的属性。

注意,子类的`__init__`方法可以接收额外的参数,以便进行子类特定的初始化操作。在示例中,子类`ChildClass`的`__init__`方法接收了`age`参数,并将其保存为子类的属性。

通过继承父类的构造方法,子类可以获得父类的属性和初始化逻辑,同时可以添加自己独有的属性和初始化操作。这样可以实现代码的重用和扩展。


reference:

9. 类 — Python 3.8.17 文档

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值