我通过一些pygame教程学习Python .
在那里我发现了关键字self的广泛使用,并且来自主要的Java背景,我发现我一直忘记键入self.例如,而不是self.rect.centerx
我要输入rect.centerx
,因为对我来说,rect已经是类的成员变量.
对于这种情况,我可以想到的Java并行是必须使用此前缀对成员变量的所有引用作为前缀.
我是否坚持使用self为所有成员变量添加前缀,或者有没有办法声明它们可以让我避免这样做?
即使我建议的不是pythonic,我仍然想知道它是否可能.
我已经看过这些相关的SO问题,但他们并没有完全回答我的想法:
小智 90
Python需要指定self. 结果是,即使没有可见的完整类定义,也不会对成员和不成员的内容产生任何混淆.这会产生有用的属性,例如:您无法添加意外影响非成员的成员,从而破坏代码.
一个极端的例子:你可以在不知道它可能具有什么基类的情况下编写一个类,并且总是知道你是否正在访问一个成员:
class A(some_function()):
def f(self):
self.member = 42
self.method()
Run Code Online (Sandbox Code Playgroud)
这是完整的代码!(some_function返回用作基础的类型.)
另一个,类的方法是动态组合的:
class B(object):
pass
print B()
# <__main__.B object at 0xb7e4082c>
def B_init(self):
self.answer = 42
def B_str(self):
return "<The answer is %s.>" % self.answer
# notice these functions require no knowledge of the actual class
# how hard are they to read and realize that "members" are used?
B.__init__ = B_init
B.__str__ = B_str
print B()
# <The answer is 42.>
Run Code Online (Sandbox Code Playgroud)
请记住,这两个示例都是极端的,您不会每天都看到它们,我也不建议您经常编写这样的代码,但它们确实清楚地显示了自我明确要求的各个方面.
Mic*_*zyk 25
实际上self
它不是一个关键字,它只是传统上赋予Python中实例方法的第一个参数的名称.并且不能跳过第一个参数,因为它是方法知道调用哪个类实例的唯一机制.
arg*_*m2f 22
以前的答案基本上都是"你不能"或"你不应该"的变体.虽然我同意后一种观点,但问题在技术上仍然没有答案.
此外,有正当理由可以解释为什么某人可能想要按照实际问题的要求做某事.有时我遇到的一件事是冗长的数学方程,其中使用长名称使方程变得无法识别.以下是一些如何在固定示例中执行此操作的方法:
import numpy as np
class MyFunkyGaussian() :
def __init__(self, A, x0, w, s, y0) :
self.A = float(A)
self.x0 = x0
self.w = w
self.y0 = y0
self.s = s
# The correct way, but subjectively less readable to some (like me)
def calc1(self, x) :
return (self.A/(self.w*np.sqrt(np.pi))/(1+self.s*self.w**2/2)
* np.exp( -(x-self.x0)**2/self.w**2)
* (1+self.s*(x-self.x0)**2) + self.y0 )
# The correct way if you really don't want to use 'self' in the calculations
def calc2(self, x) :
# Explicity copy variables
A, x0, w, y0, s = self.A, self.x0, self.w, self.y0, self.s
sqrt, exp, pi = np.sqrt, np.exp, np.pi
return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
* exp( -(x-x0)**2/w**2 )
* (1+s*(x-x0)**2) + y0 )
# Probably a bad idea...
def calc3(self, x) :
# Automatically copy every class vairable
for k in self.__dict__ : exec(k+'= self.'+k)
sqrt, exp, pi = np.sqrt, np.exp, np.pi
return ( A/( w*sqrt(pi) )/(1+s*w**2/2)
* exp( -(x-x0)**2/w**2 )
* (1+s*(x-x0)**2) + y0 )
g = MyFunkyGaussian(2.0, 1.5, 3.0, 5.0, 0.0)
print(g.calc1(0.5))
print(g.calc2(0.5))
print(g.calc3(0.5))
Run Code Online (Sandbox Code Playgroud)
第三个例子 - 即使用for k in self.__dict__ : exec(k+'= self.'+k)
基本上是问题的实际要求,但让我明确一点,我认为这通常不是一个好主意.
有关更多信息以及迭代类变量甚至函数的方法,请参阅此问题的答案和讨论.有关动态命名变量的其他方法的讨论,以及为什么这通常不是一个好主意,请参阅此博客文章.
Est*_*ber 21
例如,您可以使用任何名称
class test(object):
def function(this, variable):
this.variable = variable
Run Code Online (Sandbox Code Playgroud)
甚至
class test(object):
def function(s, variable):
s.variable = variable
Run Code Online (Sandbox Code Playgroud)
但你仍然坚持使用范围的名称.
除非你有一个令人信服的理由,否则我不建议你使用与自我不同的东西,因为它会使它对于有经验的pythonistas而言更加陌生.
是的,你必须总是指定self
,因为根据python哲学,explicit比hidden更好.
您还会发现在python中编程的方式与您在java中编程的方式有很大不同,因此使用self
往往会减少,因为您不会在对象内部投影所有内容.相反,您可以更多地使用模块级功能,这可以更好地进行测试.
顺便说说.我起初讨厌它,现在我讨厌相反的事情.对于缩进驱动的流量控制也是如此.
"self"是类的当前对象实例的传统占位符.当你想在类中引用对象的属性或字段或方法时使用它,就好像你指的是"它自己"一样.但是为了缩短Python编程领域的某些人开始使用"自我",其他领域使用"this"但他们将其作为一个无法替换的关键字.我宁愿用"它"来增加代码的可读性.它是Python中的好东西之一 - 您可以自由地为对象的实例选择自己的占位符而不是"self".自我的例子:
class UserAccount():
def __init__(self, user_type, username, password):
self.user_type = user_type
self.username = username
self.password = encrypt(password)
def get_password(self):
return decrypt(self.password)
def set_password(self, password):
self.password = encrypt(password)
Run Code Online (Sandbox Code Playgroud)
现在我们将'self'替换为'its':
class UserAccount():
def __init__(its, user_type, username, password):
its.user_type = user_type
its.username = username
its.password = encrypt(password)
def get_password(its):
return decrypt(its.password)
def set_password(its, password):
its.password = encrypt(password)
Run Code Online (Sandbox Code Playgroud)
现在哪个更具可读性?
归档时间: |
|
查看次数: |
41889 次 |
最近记录: |