我们提供的服务有:网站设计、网站建设、微信公众号开发、网站优化、网站认证、华安ssl等。为1000多家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的华安网站制作公司
近来,许多人都在抨击面向对象,虽然我不认为面向对象本身有什么问题,但我觉得至少在 Python 中没这个必要。
举个例子,比如下面的代码完全没有必要使用面向对象。
- class ApiClient:
- def __init__(self, root_url: str, session_cls: sessionmaker):
- self.root_url = root_url
- self.session_cls = session_cls
- def construct_url(self, entity: str) -> str:
- returnf"{self.root_url}/v1/{entity}"
- def get_items(self,entity: str) -> List[Item]:
- resp = requests.get(self.construct_url(entity))
- resp.raise_for_status()
- return [Item(**n) for n in resp.json()["items"]]
- def save_items(self, entity: str) -> None:
- with scoped_session(self.session_cls)as session:
- session.add(self.get_items(entity))
- class ClientA(ApiClient):
- def construct_url(self, entity: str) -> str:
- returnf"{self.root_url}/{entity}"
- class ClientB(ApiClient):
- def construct_url(self, entity: str) -> str:
- returnf"{self.root_url}/a/special/place/{entity}"
- client_a = ClientA("https://client-a",session_cls)
- client_a.save_items("bars")
这里使用了面向对象,因为我们想把 root_url 绑定到某个对象上,而且不想每次都传递 sessionmaker。我们还想使用继承,在调用的中途访问一个方法。
但如果只通过数据传递和函数能实现吗?
- @dataclass
- class Client:
- root_url: str
- url_layout: str
- client_a = Client(
- root_url="https://client-a",
- url_layout="{root_url}/{entity}",
- )
- client_b = Client(
- root_url="https://client-b",
- url_layout="{root_url}/a/special/place/{entity}",
- )
- def construct_url(client: Client, entity: str) -> str:
- returnclient.url_layout.format(root_url=client.root_url, entityentity=entity)
- def get_items(client: Client, entity: str) -> List[Item]:
- resp = requests.get(construct_url(client, entity))
- resp.raise_for_status()
- return [Item(**n) for n in resp.json()["items"]]
- def save_items(client: Client, session_cls: session_cls, entity: str) -> None:
- withscoped_session(session_cls) as session:
- session.add(get_items(client, entity))
- save_items(client_a,session_cls, "bars")
我们必须随时传递 Client 和 session_cls。
但有什么关系呢?代码量甚至还少了 10%。这样编写的代码很容易理解,而且不需要使用面向对象。
有人管这种写法叫做“函数袋”。就是说,整个代码都由有类型的数据和一大堆模块作用域的函数组成。
那么全局变量怎么处理?你可以参考这篇文章(https://leontrolski.github.io/sane-config.html),在整个应用程序的生命周期内重用 config 或 db 的 session,
接口、抽象类怎么办?实际上你不需要它们,直接写代码就行了。平心而论,Python 有了类型标注之后,函数袋风格才开始发挥真正的魅力。
不纯粹的函数怎么办?
如果你想采用纯粹的函数式编程,你可能想编写纯粹的类,然后使用不纯粹的“适配器”实例来做一些处理:getting-the-current-datetime/API-calls/talking-to-the-db/other-impure-stuff。这个想法很不错。实际上你可以直接使用 freezegun、responses 等方法来避免大量麻烦。
但也有一些例外的情况:
在极罕见的情况下(至少在应用程序的开发中很少遇到),你可能会想出一种非常好用的类型然后到处使用,就像pandas.DataFrame/sqlalchemy.Session 一样。但是一般情况下,不要自欺欺人,不要骗自己说我们正在构建了不起的应用程序。谦虚使人进步。
虽然在本文开头,我说过我不认为面向对象本身有什么问题,但实际上我还是觉得面向对象不仅没有帮助性,而且还常常混淆问题,鼓励一些不良做法:
网页名称:Python中的面向对象没有意义
网页网址:http://www.shufengxianlan.com/qtweb/news40/89040.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联