类实例化和';自我';用python
我知道关于这个问题已经写了很多。然而,我不能吸收太多。也许是因为我是一个完全的新手,在没有任何计算机科学培训的情况下自学。不管怎样,如果你们中的一些大智若愚的人加入到这个特定的例子中,也许你们会帮助像我这样的初学者 因此,我编写了以下函数,当我调用它(作为一个模块?)作为它自己的名为“funky.py”的文件时,它工作得很好: 我在终端中键入以下内容:类实例化和';自我';用python,python,class,function,instantiation,self,Python,Class,Function,Instantiation,Self,我知道关于这个问题已经写了很多。然而,我不能吸收太多。也许是因为我是一个完全的新手,在没有任何计算机科学培训的情况下自学。不管怎样,如果你们中的一些大智若愚的人加入到这个特定的例子中,也许你们会帮助像我这样的初学者 因此,我编写了以下函数,当我调用它(作为一个模块?)作为它自己的名为“funky.py”的文件时,它工作得很好: 我在终端中键入以下内容: python classy.py 而且运行良好 def load_deck(): suite = ('Spades', 'Hearts
python classy.py
而且运行良好
def load_deck():
suite = ('Spades', 'Hearts')
rank = ('2', '3')
full_deck = {}
i = 0
for s in suite:
for r in rank:
full_deck[i] = "%s of %s" % (r, s)
i += 1
return full_deck
print load_deck()
然而,当我将相同的函数放入一个类中时,我得到了一个错误
这是我的“classy.py”代码:
class GAME():
def load_deck():
suite = ('Spades', 'Hearts')
rank = ('2', '3')
full_deck = {}
i = 0
for s in suite:
for r in rank:
full_deck[i] = "%s of %s" % (r, s)
i += 1
return full_deck
MyGame = GAME()
print MyGame.load_deck()
我得到以下错误:
Traceback (most recent call last):
File "classy.py", line 15, in <module>
print MyGame.load_deck()
TypeError: load_deck() takes no arguments (1 given)
将一个函数放入一个需要使用“self”的类中是什么。我明白“自我”只是一种惯例。那么,为什么需要争论呢?从类中调用函数时,函数的行为是否不同
而且,这几乎更重要,为什么我的课堂没有使用init?使用init对我的课堂有什么作用
基本上,如果有人有时间像我6岁那样向我解释这一点,这会有所帮助。提前感谢您的帮助。在类定义中定义函数会调用一些魔法,将其转换为方法描述符。当您访问foo.method时,它将自动创建绑定方法并将对象实例作为第一个参数传递。您可以通过使用@staticmethod装饰器来避免这种情况
\uuuu init\uuuu
只是在创建类以执行可选设置时调用的方法<代码>\uuuu新建\uuuu是实际创建对象的内容
这里有一些例子
>>> class Foo(object):
def bar(*args, **kwargs):
print args, kwargs
>>> foo = Foo()
>>> foo.bar
<bound method Foo.bar of <__main__.Foo object at 0x01C9FEB0>>
>>> Foo.bar
<unbound method Foo.bar>
>>> foo.bar()
(<__main__.Foo object at 0x01C9FEB0>,) {}
>>> Foo.bar()
Traceback (most recent call last):
File "<pyshell#29>", line 1, in <module>
Foo.bar()
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.bar(foo)
(<__main__.Foo object at 0x01C9FEB0>,) {}
>>类Foo(对象):
定义栏(*args,**kwargs):
打印args,kwargs
>>>foo=foo()
>>>美食酒吧
>>>美食酒吧
>>>foo.bar()
(,) {}
>>>Foo.bar()
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
Foo.bar()
TypeError:必须使用Foo实例作为第一个参数调用unbound方法bar()(但没有得到任何结果)
>>>Foo.bar(Foo)
(,) {}
那么,为什么需要争论呢
访问类的当前实例上的属性
假设您有一个具有两种方法的类,load\u deck
和shuffle
。在load_-deck
的末尾,您希望洗牌(通过调用shuffle
方法)
在Python中,您可以执行以下操作:
class Game(object):
def shuffle(self, deck):
return random.shuffle(deck)
def load_deck(self):
# ...
return self.shuffle(full_deck)
将其与大致等同的C++代码进行比较:
class Game {
shuffle(deck) {
return random.shuffle(deck);
}
load_deck() {
// ...
return shuffle(full_deck)
}
}
在shuffle(full_-deck)
行中,它首先查找名为shuffle
的局部变量-该变量不存在,然后检查更高一级,并找到名为shuffle
的实例方法(如果不存在,它将检查具有正确名称的全局变量)
这没关系,但不清楚shuffle是指某个局部变量还是实例方法。为了解决这种模糊性,还可以通过this
访问实例方法或实例属性:
...
load_deck() {
// ...
return this->shuffle(full_deck)
}
这个
与Python本身几乎相同,只是它没有作为参数传递
为什么将self
作为有用的参数是有用的这些可通过以下行进行总结:
这是由博客中的一篇文章支持的
我决定放弃隐式引用实例变量的想法。像C++这样的语言让你写这个-> FO来显式引用实例变量FO(如果有单独的局部变量FO)。因此,我决定将这种显式引用作为引用实例变量的唯一方法。此外,我决定不将当前对象(“this”)作为一个特殊的关键字,而是将“this”(或其等价物)作为方法的第一个命名参数。实例变量总是作为该参数的属性引用
对于显式引用,不需要为方法定义使用特殊语法,也不必担心变量查找的复杂语义。相反,我们只需定义一个函数,其第一个参数对应于实例,按照惯例称之为“self”
如果您不打算使用self,您可能应该将该方法声明为静态方法
class Game:
@staticmethod
def load_deck():
....
这将撤消自动默认打包,该打包通常会将类范围中的函数转换为以实例为参数的方法
传递您不使用的参数会让其他试图阅读您的代码的人感到不安
大多数班级都有成员。你的不是,所以它的所有方法都应该是静态的。随着项目的发展,您可能会发现其中所有功能都可以访问的数据,您会将这些数据放入self,并将其传递给所有功能
在此上下文中,应用程序本身是您的主要对象,\uuu init\uuu只是初始化所有这些共享值的函数
这是迈向面向对象风格的第一步,在这种风格中,较小的数据片段被用作对象本身。但这是从直接脚本到OO编程的正常阶段。主要的一点是,一个类有许多实例-您需要
self
知道您正在处理哪个实例。如果你不需要很多实例,你应该问问自己是否需要一个类。这是一个开始。什么是边界方法?将对象实例作为第一个参数传递意味着什么?这是否意味着函数将函数本身作为第一个参数传递?传给什么?还有,为什么?写“self”能解决什么问题?绑定方法意味着对象实例已经作为第一个参数传递。你可以把它想象成一只羔羊。一个未绑定的方法就是当你
Explicit is better than implicit.
class Game:
@staticmethod
def load_deck():
....