3

一日一技:应该传入对象还是在用的时候再初始化?

 2 years ago
source link: https://www.kingname.info/2020/03/23/pass-or-create/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

一日一技:应该传入对象还是在用的时候再初始化?

发表于

2020-03-23

| 分类于 Python

| 评论数: 1

在写 Python 代码的时候,大家可能会在不知不觉中使用一些设计范式。我们来看两个例子。

假设有一个类People

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

def dance(self):
print('我在跳舞')

def study(self):
print('我在学习')

def eat(self):
print('我在吃东西')

现在我们有另一个类ClassRoom:

class ClassRoom:
def __init__(self, size):
self.size = size
self.student = People('小明', 17, '男')

def start_class(self):
self.student.study()

我们在ClassRoom的构造函数中,初始化了一个 student 对象,然后在start_class方法中,调用了这个对象的study方法。

这个过程看起来似乎没有什么问题,相信很多读者也是这样写代码的。

现在,我们再增加两个类:

class Restaurant:
def __init__(self, name):
self.name = name
self.consumer = People('张三', 30, '男')

def start_launch(self):
self.consumer.eat()
class Ballroom:
def __init__(self, address):
self.address = address
self.dancer = People('小红', 20, '女')

def open(self):
self.dancer.dance()

新增加的两个类RestaurantBallroom的构造函数里面都通过People类初始化了对象。然后在调用这个对象的方法。

这样写看起来没有问题,能正常工作,代码也不丑。

现在,People类需要修改一下它的构造函数:

class People:
def __init__(self, name, age, sex, address):
self.name = name
self.age = age
self.sex = sex

def dance(self):
print('我在跳舞')

def study(self):
print('我在学习')

def eat(self):
print('我在吃东西')

在初始化People类时,需要传入一个address参数。现在怎么办?

于是ClassRoomRestaurantBallroom这三个类的构造函数都要随之做修改,全都得加上这个address参数。

这就叫做牵一发而动全身

很多人为了避免做这样的修改,会把新增加的这个参数address改成默认参数:

class People:
def __init__(self, name, age, sex, address=''):
self.name = name
self.age = age
self.sex = sex

def dance(self):
print('我在跳舞')

def study(self):
print('我在学习')

def eat(self):
print('我在吃东西')

这样看起来,另外三个类的代码就不需要做任何修改了。

这就是为什么你们公司的代码里面,很多函数会带上大量奇奇怪怪的默认参数的原因。

在编程范式中,有一个术语叫做依赖注入,就是为了解决这个问题的。

而且做起来简单到你觉得这是在逗你,把People初始化以后的对象传到其他类的构造函数中即可:

class Ballroom:
def __init__(self, address, dancer):
self.address = address
self.dancer = dancer

def open(self):
self.dancer.dance()

dancer = People('小红', 20, '女')
ballroom = Ballroom('xxx', dancer)
ballroom.open()

虽然叫做编程范式,但也不是说应该始终使用依赖注入。例如你的代码会层层调用,难道从第一层把对象一层一层传到最里面去?所以应该根据实际情况来进行选择。


Recommend

  • 68

    弹窗非常容易打断正常工作:事情干得好好的,忽然一个弹窗贴着你的脸蹦出来,非得腾出手去摸鼠标,瞄准了弹窗上的按钮再点下去。文件名冲突、文件重复、删除 iCloud 文件(默认会提醒)等常见情况下,弹窗都会如期而至。 Mac 用...

  • 38

    Matrix 精选 Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。 文章代表作者个人观点,少数派仅对标...

  • 16

    出于保护用户隐私信息的目的,Android 对各类应用能够索取到的权限不断收紧。从用户角度来说,我们无需再绞尽脑汁和过度索取权限的应用斗智斗勇,这无疑是新系统带来的一大利好。 关联阅读:

  • 24

    Matrix 精选 Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。 文章代表作者个人观点,少数...

  • 74

    某次 Magisk 版本升级后,就陆续有读者来向我反馈字体模块失效的问题。当然,除了我们这些热衷于换字体的人,其它用户在这次更新后也会遇到模块刷入后没有任何效果的情况。 为什么会出现这样的现象呢? 如果你有自制 M...

  • 31

    作为 Android 社区最热门、最有活力也最有魅力的玩机工具之一,Magisk 简单易用、相对安全、可玩性高的特点一直以来都广受赞誉,依赖挂载方式的模块化系统定制思路让它即便对一些刚刚转入 Android 阵营的新用户而言也充满了吸引力。...

  • 22

    Matrix 首页推荐 Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。 文章代表作者个人观点,少数派仅...

  • 19

    摄影:产品经理 这个锅巴不好吃 Scrapy自带的 FilesPipeline

  • 3

    一日一技:Python如何动态替换对象的方法? 2023-01-01 2 522 2 分钟 今天有同学在公众号粉丝群问了这样一个问题:

  • 5
    • www.kingname.info 6 months ago
    • Cache

    一日一技:JSON如何快速转成对象?

    一日一技:JSON如何快速转成对象? 2023-09-22 45 362 1 分钟 我们知道,在Python里面,要把JSON转成字典是非常容易的,只需要使用json.loads(JSON字符串)

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK