DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • python面向过程

  • python面向对象

    • OOP基本
    • 继承和组合
    • 多态与多态性
    • 封装与接口
    • 绑定与非绑定方法
      • 绑定方法
        • ☆分类 self  cls
        • ☆应用
      • 非绑定方法
        • @staticmethod
        • 体会区别
    • 简单总结
    • 反射、内置方法
    • 元类
    • 异常处理
    • 小项目之course_select
    • 复习
  • 网络并发编程

  • 不基础的py基础

  • 设计模式

  • python_Need
  • python面向对象
DC
2023-08-16
目录

绑定与非绑定方法

# 绑定方法

绑定给谁就应该由谁来 调用.谁来调用就会将谁当作第一个参数自动传入.

精髓在于 --- 自动传值

# ☆分类 self  cls

1>绑定给实例化对象的方法
     在类内部定义的函数(第一个参数约定俗成写为self+没有被任何装饰器修饰),通常默认就是绑定给对象用的.
反过来理解,类中没有被装饰器绑定的函数,就是绑定给实例化对象用的,对象使用时,会自动将自己传入, 所以此函数需要有一个形参来接受, 此形参约定写成self.便于区分.
有一些__开头的函数属于特殊情况... 特殊情况特殊分析

2>绑定给类的方法
     在类内部定义的函数(第一个参数约定俗成写为cls)若被装饰器@classmethod装饰器装饰,
     那么则是绑定给类的,应该由类来调用,会自动将类当作第一个参数自动传入

class Foo:

    @classmethod
    def f1(cls):
        print(cls)

    def f2(self):
        print(self)


obj = Foo()

# -- 绑定给类的
# ★ 了解:绑定给类的应该由类来调用,但实例化对象其实也可以使用,只不过自动传入的仍然是类.
print(Foo.f1)  # <bound method Foo.f1 of <class '__main__.Foo'>>
print(obj.f1)  # <bound method Foo.f1 of <class '__main__.Foo'>>
Foo.f1()  # <class '__main__.Foo'>
obj.f1()  # <class '__main__.Foo'>

# -- 绑定给实例化对象的
print(obj.f2)  # <bound method Foo.f2 of <__main__.Foo object at 0x7f90898498e0>>
print(Foo.f2)  # <function Foo.f2 at 0x7f9089848b80> 普通方法 该传多少参数就传多少参数
obj.f2()  # <__main__.Foo object at 0x7f90898498e0>
Foo.f2()  # 报错:f2() missing 1 required positional argument: 'self'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# ☆应用

若函数体代码需要用外部传入的类, 则应该将该函数定义成绑定给类的方法.
若函数体代码需要用外部传入的实例化对象, 则应该将该函数定义成绑定给对象的方法.

默认 的实例化方式: 类名( )
新的 实例化方式: 从配置文件中读取配置完成实例化!

"""
# -- setting.py
HOST = '127.0.0.1'
PORT = 3306
"""
import settings

class MySQL:
    def __init__(self, host, port):
        self.host = host
        self.port = port

    def tell_info(self):
        print(f'IP地址:{self.host},端口:{self.port}')

    @classmethod
    def from_conf(cls):
        print(cls)
        return cls(settings.HOST, settings.PORT)

      
# conn = MySQL('127.0.0.1',3306)
conn = MySQL.from_conf()
conn.tell_info()  # IP地址:127.0.0.1,端口:3306
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 非绑定方法

类中定义的函数如果被装饰器@staticmethod装饰,那么该函数就变成非绑定方法.

既不与类绑定,又不与对象绑定, 意味着类与对象都可以来调用 但无论谁来调用, 都 没有 任何 自动传值 的效果 .. 就是一个普通函数!!

# @staticmethod

应用: 如果函数体代码既不需要外部传入的类也不需要外部传入的对象, 则应该将该函数定义成非绑定方法.

Q: 思考 => 不加@staticmethod,直接在类中定义, def func():pass 河狸吗?
A:[不合理] 还是老生常谈的一个问题,类中不加装饰器的函数默认是绑定给实例化对象使用的.
     实例化对象调用func, 发现func方法没有参数接收自动传入的对象自己.
     直接报错:func() takes 0 positional arguments but 1 was given

import uuid

class A:
    def __init__(self):
        self.uid = self.create_id()

    @staticmethod
    def func1(x, y):
        print('这是一个非绑定方法..')

    @staticmethod
    def create_id():
        return uuid.uuid1()

a = A()
print(a.func1)  # <function A.func1 at 0x7f806805b5e0>
print(A.func1)  # <function A.func1 at 0x7f806805b5e0>
a.func1(1, 2)  # 这是一个非绑定方法..
A.func1(1, 2)  # 这是一个非绑定方法..

"""
UUID是128位的全局唯一标识符,通常由32字节的字符串表示.它可以保证时间和空间的唯一性.

uuid1() 基于时间戳的算法
	由MAC地址、当前时间戳、随机数生成. 可以保证全球范围内的唯一性
	但MAC的使用同时带来安全性问题,局域网中可以使用IP来代替MAC

UUID主要有五个算法
首先,Python中没有基于DCE的,所以uuid2可以忽略;
其次,uuid4存在概率性重复,最好不用;
再次,若在Global的分布式计算环境下,最好用uuid1;
最后,若有名字的唯一性要求,最好用uuid3或uuid5.
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 体会区别

PS: 体会classmethod与staticmethod的区别

我们的意图是想触发Mariadb.__str__,但是结果触发了MySQL.__str__的执行.
因为返回的m是MySQ类产生的... return MySQL(settings.HOST, settings.PORT)

import settings


class MySQL:

    def __init__(self, host, port):
        self.host = host
        self.port = port

    @staticmethod
    def from_conf():
        return MySQL(settings.HOST, settings.PORT)

    # @classmethod #哪个类来调用,就将哪个类当做第一个参数传入
    # def from_conf(cls):
    #     return cls(settings.HOST,settings.PORT) # 哪个类来调用,即用哪个类cls来实例化

    def __str__(self):
        return '就不告诉你'


class Mariadb(MySQL):

  	# __str__方法需要返回一个字符串当做对这个实例化对象的描写
    def __str__(self):
        return '<%s:%s>' % (self.host, self.port)


m = Mariadb.from_conf()
print(m)  #我们的意图是想触发Mariadb.__str__,但是结果触发了MySQL.__str__的执行,打印就不告诉你:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

总结绑定方法与非绑定方法的使用:
     若类中需要一个功能, 该功能的实现代码中需要引用对象则将其定义成对象方法;
     需要引用类则将其定义成类方法;
     无需引用类或对象则将其定义成静态方法.


封装与接口
简单总结

← 封装与接口 简单总结→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式