想想这个例子:
class MyClass:
def func(self, name):
self.name = name
我知道self引用MyClass的特定实例。但是为什么func必须显式地包含self作为参数呢?为什么我们需要在方法的代码中使用self ?其他一些语言将其隐式化,或者使用特殊的语法。
有关设计决策的语言无关性考虑,请参见强制显式使用this/self指针的好处是什么?
要关闭OP省略方法的self形参并获得TypeError的调试问题,请使用TypeError: method()接受1个位置参数,但给出了2个。如果OP省略了self。在方法体中得到一个NameError,考虑如何在类中调用函数?
首先,self是一个传统的名字,你可以用其他任何东西(连贯)来代替它。
它引用对象本身,因此当您使用它时,您声明.name和.age是您将要创建的Student对象(注意,不是Student类)的属性。
class Student:
#called each time you create a new Student instance
def __init__(self,name,age): #special method to initialize
self.name=name
self.age=age
def __str__(self): #special method called for example when you use print
return "Student %s is %s years old" %(self.name,self.age)
def call(self, msg): #silly example for custom method
return ("Hey, %s! "+msg) %self.name
#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)
#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self
#you can modify attributes, like when alice ages
alice.age=20
print alice
代码在这里
首先,self是一个传统的名字,你可以用其他任何东西(连贯)来代替它。
它引用对象本身,因此当您使用它时,您声明.name和.age是您将要创建的Student对象(注意,不是Student类)的属性。
class Student:
#called each time you create a new Student instance
def __init__(self,name,age): #special method to initialize
self.name=name
self.age=age
def __str__(self): #special method called for example when you use print
return "Student %s is %s years old" %(self.name,self.age)
def call(self, msg): #silly example for custom method
return ("Hey, %s! "+msg) %self.name
#initializing two instances of the student class
bob=Student("Bob",20)
alice=Student("Alice",19)
#using them
print bob.name
print bob.age
print alice #this one only works if you define the __str__ method
print alice.call("Come here!") #notice you don't put a value for self
#you can modify attributes, like when alice ages
alice.age=20
print alice
代码在这里
让我们看一个简单的向量类:
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
我们需要一个计算长度的方法。如果我们想在类中定义它会是什么样子呢?
def length(self):
return math.sqrt(self.x ** 2 + self.y ** 2)
当我们将它定义为全局方法/函数时,它应该是什么样子?
def length_global(vector):
return math.sqrt(vector.x ** 2 + vector.y ** 2)
所以整个结构保持不变。我怎样才能利用这个呢?假设我们还没有为Vector类编写length方法,我们可以这样做:
Vector.length_new = length_global
v = Vector(3, 4)
print(v.length_new()) # 5.0
这是因为length_global的第一个参数可以重用为length_new中的self参数。如果没有显式的自我,这是不可能的。
另一种理解显式self需求的方法是查看Python在哪里添加了一些语法糖。当你记住的时候,基本上,一个电话就像
v_instance.length()
在内部转化为
Vector.length(v_instance)
很容易看出自我在哪里。实际上你不用在Python中编写实例方法;你所写的是类方法,它必须以一个实例作为第一个参数。因此,必须显式地将实例参数放置在某个位置。
这个参数的使用,通常称为self并不难理解,为什么它是必要的呢?或者为什么要明确地提到它?我想,对于大多数查找这个问题的用户来说,这是一个更大的问题,如果不是,他们在继续学习python时肯定会有同样的问题。我建议他们阅读以下几篇博客:
1:使用自我解释
注意,它不是关键字。
每个类方法(包括init)的第一个参数始终是对类当前实例的引用。按照惯例,这个参数总是命名为self。在init方法中,self指向新创建的对象;在其他类方法中,它引用被调用方法的实例。例如,下面的代码与上面的代码相同。
2:为什么我们要这样做,为什么我们不能像Java那样把它作为一个参数,而是用一个关键字来代替
我想补充的另一件事是,一个可选的self参数允许我在一个类中声明静态方法,不写self。
代码示例:
class MyClass():
def staticMethod():
print "This is a static method"
def objectMethod(self):
print "This is an object method which needs an instance of a class, and that is what self refers to"
PS:这只适用于Python 3.x。
在以前的版本中,您必须显式地添加@staticmethod装饰器,否则self参数是必须的。