gpt4 book ai didi

Python 名称修改

转载 作者:IT老高 更新时间:2023-10-28 21:11:27 27 4
gpt4 key购买 nike

在其他语言中,有助于生成更好代码的一般准则始终是尽可能隐藏所有内容。如果不确定变量应该是私有(private)的还是 protected ,最好使用私有(private)。

Python 也是如此吗?我应该首先在所有内容上使用两个前导下划线,并且只在我需要时使它们不那么隐藏(只有一个下划线)吗?

如果约定仅使用一个下划线,我也想知道其基本原理。

这是我在 JBernardo's answer 上留下的评论。它解释了我问这个问题的原因以及为什么我想知道 Python 与其他语言不同的原因:

I come from languages that train you to think everything should be only as public as needed and no more. The reasoning is that this will reduce dependencies and make the code safer to alter. The Python way of doing things in reverse -- starting from public and going towards hidden -- is odd to me.

最佳答案

如有疑问,请将其保留为“公开” - 我的意思是,不要添加任何内容来掩盖您的属性名称。如果您有一个具有某些内部值的类,请不要理会它。而不是写:

class Stack(object):

def __init__(self):
self.__storage = [] # Too uptight

def push(self, value):
self.__storage.append(value)
默认写这个:
class Stack(object):

def __init__(self):
self.storage = [] # No mangling

def push(self, value):
self.storage.append(value)
这无疑是一种有争议的做事方式。 Python 新手讨厌它,甚至一些老 Python 人也鄙视这种默认设置——但无论如何它都是默认设置,所以我建议你遵循它,即使你觉得不舒服。
如果你真的想发送消息“不能碰这个!”对于您的用户,通常的方法是在变量前面加上一个下划线。这只是一个约定,但人们理解它并在处理此类事情时加倍小心:
class Stack(object):

def __init__(self):
self._storage = [] # This is ok, but Pythonistas use it to be relaxed about it

def push(self, value):
self._storage.append(value)
这对于避免属性名称和属性名称之间的冲突也很有用:
 class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0

@property
def age(self):
return self._age

@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
双下划线呢?那么,我们主要使用双下划线魔术 to avoid accidental overloading of methods and name conflicts with superclasses' attributes .如果您编写一个要扩展多次的类,这可能非常有值(value)。
如果你想将它用于其他目的,你可以,但它既不常用也不推荐。
编辑 : 为什么会这样?好吧,通常的 Python 风格并不强调将事情私有(private)化——恰恰相反!造成这种情况的原因有很多——其中大部分是有争议的……让我们看看其中的一些。
Python有属性
今天,大多数面向对象语言使用相反的方法:不应该使用的东西不应该是可见的,所以属性应该是私有(private)的。从理论上讲,这会产生更易于管理、耦合更少的类,因为没有人会鲁莽地更改对象的值。
然而,事情并非如此简单。例如,Java 类有许多只获取值的 getter 和只设置值的 setter。比如说,您需要七行代码来声明一个属性——Python 程序员会说这是不必要的复杂。此外,您编写了大量代码来获取一个公共(public)字段,因为您可以在实践中使用 getter 和 setter 更改其值。
那么为什么要遵循这个默认私有(private)的策略呢?只需默认公开您的属性即可。当然,这在 Java 中是有问题的,因为如果您决定为属性添加一些验证,则需要您更改所有内容:
person.age = age;
在你的代码中,让我们说,
person.setAge(age);
setAge()是:
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
this.age = 0;
}
}
因此,在 Java(和其他语言)中,默认情况下无论如何都使用 getter 和 setter,因为它们编写起来可能很烦人,但如果您发现自己处于我所描述的情况,它们可以为您节省很多时间。
但是,您不需要在 Python 中执行此操作,因为 Python 具有属性。如果你有这个类:
 class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
...然后您决定验证年龄,您无需更改 person.age = age你的代码片段。只需添加一个属性(如下图)
 class Person(object):
def __init__(self, name, age):
self.name = name
self._age = age if age >= 0 else 0

@property
def age(self):
return self._age

@age.setter
def age(self, age):
if age >= 0:
self._age = age
else:
self._age = 0
假设你可以做到并且仍然使用 person.age = age ,为什么要添加私有(private)字段和 getter 和 setter?
(另请参阅 Python is not Javathis article about the harms of using getters and setters 。)。
无论如何,一切都是可见的 - 试图隐藏会使您的工作复杂化
即使在具有私有(private)属性的语言中,您也可以通过一些反射/内省(introspection)库访问它们。人们经常这样做,在框架中并为了解决紧急需求。问题在于,内省(introspection)库只是一种复杂的方式,可以执行您可以使用公共(public)属性执行的操作。
由于 Python 是一种非常动态的语言,将这种负担添加到您的类中会适得其反。
问题是无法看到 - 需要看到
对于 Pythonista 来说,封装不是无法看到类的内部结构,而是避免查看它的可能性。封装是组件的属性,用户可以使用它而无需关心内部细节。如果您可以使用一个组件而不必为它的实现而烦恼,那么它就是被封装的(在 Python 程序员看来)。
现在,如果你写了一个类,你可以不用考虑实现细节就可以使用它,如果你出于某种原因想要查看类内部,那也没有问题。重点是:你的API要好,剩下的就是细节。
圭多这么说
嗯,这没有争议: he said so, actually . (寻找“开放式和服”。)
这是文化
是的,有一些原因,但不是关键原因。这主要是 Python 编程的文化方面。坦率地说,它也可能是另一种方式——但事实并非如此。此外,您也可以反过来问:为什么有些语言默认使用私有(private)属性?出于与 Python 实践相同的主要原因:因为这是这些语言的文化,每种选择都有优点和缺点。
既然已经有这种文化,建议你遵循它。否则,你会被 Python 程序员告诉你删除 __ 惹恼。当您在 Stack Overflow 中提问时从您的代码中提取:)

关于Python 名称修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7456807/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com