简体   繁体   English

什么是使用私有变量的Pythonic方法?

[英]What is the Pythonic way to use private variables?

I recently posted a question on stackoverflow and I got a resolution. 我最近发布了一个关于stackoverflow 的问题 ,我得到了一个解决方案。

Some one suggested to me about the coding style and I haven't received further input. 有人向我建议编码风格,我没有收到进一步的意见。 I have the following question with reference to the prior query. 我参考先前的查询有以下问题。

  1. How can we declare private variables inside a class in python? 我们如何在python中的类中声明私有变量? I thought that by using a double underscore (__) the variable is treated as private. 我认为通过使用双下划线(__),变量被视为私有。 Please correct me. 请指正。

  2. As per the suggestion received before, we don't have to use a getter or setter method. 根据之前收到的建议,我们不必使用getter或setter方法。 Shouldn't we use a getter or setter or both? 我们不应该使用吸气剂或二传剂或两者兼而有之吗? Please let me know your suggestion on this one. 请让我知道你对此的建议。

Everything is public in Python, the __ is a suggestion by convention that you shouldn't use that function as it is an implementation detail. 在Python中,一切都是public的, __是一种惯例建议,你不应该使用该函数,因为它是一个实现细节。

This is not enforced by the language or runtime in any way, these names are decorated in a semi-obfuscated way, but they are still public and still visible to all code that tries to use them. 这不是由语言或运行时以任何方式强制执行的,这些名称以半混淆的方式进行修饰,但它们仍然是public并且对于尝试使用它们的所有代码仍然可见。

Idiomatic Python doesn't use get/set accessors, it is duplication of effort since there is no private scope. 惯用Python不使用get / set访问器,因为没有private范围,所以重复工作。

You only use accessors when you want indirect access to a member variable to have code around it, and then you mark the member variable with __ as the start of its name and provide a function with the actual name. 如果希望间接访问成员变量以获得代码,则只使用访问器,然后使用__作为其名称的开头标记成员变量,并提供具有实际名称的函数。

You could go to great lengths with writing reams of code to try and protect the user from themselves using Descriptors and meta programming, but in the end you will end up with more code that is more to test and more to maintain, and still no guarantee that bad things won't happen. 您可以通过编写大量代码来尝试使用描述符和元编程来保护用户自己,但最终您将获得更多代码,更多的是测试和更多维护,但仍然无法保证不好的事情不会发生。 Don't worry about it - Python has survived 20 years this way so far, so it can't be that big of a deal. 不用担心 - 到目前为止,Python已经以这种方式存活了20年,所以它不是那么大的交易。

PEP 8 ( http://www.python.org/dev/peps/pep-0008/ ) has a section "Designing for inheritance" that should address most of these concerns. PEP 8( http://www.python.org/dev/peps/pep-0008/ )有一节“设计继承”,应该解决大多数这些问题。

To quote: 报价:

"We don't use the term "private" here, since no attribute is really private in Python (without a generally unnecessary amount of work)." “我们在这里不使用术语”私有“,因为Python中没有任何属性是私有的(没有通常不必要的工作量)。”

Also: 也:

"If your class is intended to be subclassed, and you have attributes that you do not want subclasses to use, consider naming them with double leading underscores and no trailing underscores." “如果您的类要进行子类化,并且您有不希望子类使用的属性,请考虑使用双前导下划线和没有尾随下划线来命名它们。”

If you've not read the entire section, I would encourage you to do so. 如果您没有阅读整个部分,我会鼓励您这样做。

Update: 更新:

To answer the question (now that the title has changed). 回答这个问题(现在标题已经改变)。 The pythonic way to use private variables, is to not use private variables. 使用私有变量的pythonic方法是使用私有变量。 Trying to hide something in python is seldom seen as pythonic. 试图隐藏python中的东西很少被视为pythonic。

You can use Python properties instead of getters and setters. 您可以使用Python属性而不是getter和setter。 Just use an instance attribute and when you need something more complex, make this attribute a property without changing too much code. 只需使用实例属性,当您需要更复杂的东西时,将此属性设为属性,而不会更改太多代码。

http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/ http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/

Private variables: 私人变量:

If you use the double underscore at the beginning of your class members they are considered to be private, though not REALLY enforced by python. 如果你在类成员的开头使用双下划线,那么它们被认为是私有的,尽管python并没有真正强制执行。 They simply get some naming tacked on to the front to prevent them from being easily accessed. 他们只是在前面添加了一些命名,以防止它们被轻易访问。 Single underscore could be treated as "protected". 单下划线可视为“受保护”。

Getter/Setter: 的getter / setter:

You can use these if you want to do more to wrap the process and 'protect' your 'private' attributes. 如果您想要做更多的事情来包装流程并“保护”您的“私有”属性,则可以使用这些。 But its, again, not required. 但它再次不是必需的。 You could also use Properties, which has getter/setter features. 您还可以使用具有getter / setter功能的Properties。

1) http://docs.python.org/tutorial/classes.html#private-variables 1) http://docs.python.org/tutorial/classes.html#private-variables

“Private” instance variables that cannot be accessed except from inside an object don't exist in Python. Python中不存在除了从对象内部访问之外无法访问的“私有”实例变量。 However, there is a convention that is followed by most Python code: a name prefixed with an underscore (eg _spam) should be treated as a non-public part of the API (whether it is a function, a method or a data member). 但是,大多数Python代码都遵循一个约定:前缀为下划线的名称(例如_spam)应被视为API的非公共部分(无论是函数,方法还是数据成员) 。 It should be considered an implementation detail and subject to change without notice. 它应被视为实施细节,如有更改,恕不另行通知。

(continue reading for more details about class-private variables and name mangling) (继续阅读有关类私有变量和名称修改的更多详细信息)

2) http://docs.python.org/library/functions.html#property 2) http://docs.python.org/library/functions.html#property

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM