Python变量声明

bsr*_*bsr 77 python variable-declaration python-2.7 python-3.x

学习python,并有一些基本的疑虑.

我看过变量声明(路径在这里)

class writer:
    path = ""
Run Code Online (Sandbox Code Playgroud)

有时,没有明确的声明,但初始化__init__.

def __init__(self, name):
    self.name = name
Run Code Online (Sandbox Code Playgroud)

我理解的目的__init__,但是建议在任何其他函数中声明变量.

2.如何创建变量来保存自定义类型?

class writer:
    path = "" # string value
    customObj = ??
Run Code Online (Sandbox Code Playgroud)

Kar*_*tel 190

好的,首先要做的事情.

Python中没有"变量声明"或"变量初始化"这样的东西.

简直就是我们所谓的"任务",但应该只是称之为"命名".

分配意味着"左侧的这个名称现在指的是评估右侧的结果,无论它之前提到的是什么(如果有的话)".

foo = 'bar' # the name 'foo' is now a name for the string 'bar'
foo = 2 * 3 # the name 'foo' stops being a name for the string 'bar',
# and starts being a name for the integer 6, resulting from the multiplication
Run Code Online (Sandbox Code Playgroud)

因此,Python的名称(比"变量"更好的术语,可以说)没有关联的类型; 价值观.您可以将相同的名称重新应用于任何类型,无论其类型如何,但事物仍然具有依赖于其类型的行为.该名称只是一种引用值(对象)的方法.这回答了您的第二个问题:您创建变量来保存自定义类型.您不创建变量来保存任何特定类型.你根本不"创造"变量.你给对象命名.

第二点:当涉及到类时,Python遵循一个非常简单的规则,实际上比Java,C++和C#等语言更加一致:内声明的所有内容都是class类的一部分.因此,def这里编写的functions()是方法,即类对象的一部分(不是基于每个实例存储),就像在Java,C++和C#中一样; 但这里的其他名字也是班级的一部分.同样,名称只是名称,它们没有关联类型,函数也是 Python 中的对象.从而:

class Example:
    data = 42
    def method(self): pass
Run Code Online (Sandbox Code Playgroud)

在Python中,类也是对象.

所以现在我们创建了一个名为的对象Example,它代表了所有东西的类Example.该对象有两个用户提供的属性(在C++中,"成员";在C#中,"字段或属性或方法";在Java中,"字段或方法").其中一个是命名的data,它存储整数值42.另一个是命名的method,它存储一个函数对象.(Python自动添加了几个属性.)

但是,这些属性仍然不是对象的一部分.从根本上说,一个对象只是一堆更多的名称(属性名称),直到你找到不能再分割的东西.因此,如果您故意设置了值,则可以在类的不同实例之间共享值,甚至可以在不同类的对象之间共享.

让我们创建一个实例:

x = Example()
Run Code Online (Sandbox Code Playgroud)

现在我们有一个名为的单独对象x,它是一个实例Example.的datamethod实际上不是对象的一部分,但我们仍然可以找一找通过x的,因为有些魔力,Python做幕后.当我们仰望method,特别是,我们反而会得到一个"绑定方法"(当我们调用它,x被作为自动传递self参数,如果我们仰望这是不可能发生的Example.method直接).

当我们尝试使用时会发生什么x.data

当我们检查它时,它首先在对象中查找.如果在对象中找不到它,Python会在类中查找.

但是,当我们分配时 x.data,Python将在对象上创建一个属性.它不会取代类的属性.

这允许我们进行对象初始化.Python将__init__在创建新实例时自动调用类' 方法(如果存在).在这个方法中,我们可以简单地分配属性来为每个对象设置该属性的初始值:

class Example:
    name = "Ignored"
    def __init__(self, name):
        self.name = name
    # rest as before
Run Code Online (Sandbox Code Playgroud)

现在我们必须指定一个name创建时间Example,每个实例都有自己的实例name.Example.name每当我们查找.name实例时,Python都会忽略class属性,因为首先会找到实例的属性.

最后一点需要注意:修改(变异)和赋值是不同的事情!

在Python中,字符串是不可变的.它们无法修改.当你这样做时:

a = 'hi '
b = a
a += 'mom'
Run Code Online (Sandbox Code Playgroud)

不会更改原始的"hi"字符串.这在Python中是不可能的.相反,您创建一个字符串'hi mom',并导致a不再是一个名称'hi ',并开始成为一个名称'hi mom'.我们也给b了一个名字'hi ',在重新申请a名字后,b仍然是一个名字'hi ',因为它'hi '仍然存在并且没有被改变.

但列表可以更改:

a = [1, 2, 3]
b = a
a += [4]
Run Code Online (Sandbox Code Playgroud)

现在b也是[1,2,3,4],因为我们ba命名相同的东西命名,然后我们改变了那个东西.我们没有为aname命名创建一个新列表,因为Python只是对+=列表采用不同的方式.

这对于对象很重要,因为如果您有一个列表作为类属性,并使用实例来修改列表,那么更改将在所有其他实例中"看到".这是因为(a)数据实际上是类对象的一部分,而不是任何实例对象; (b)因为您正在修改列表而没有进行简单的赋值,所以您没有创建隐藏class属性的新实例属性.

  • 这就是我们称之为['identifiers'](http://docs.python.org/2/reference/lexical_analysis.html#identifiers)的原因.:-) (12认同)
  • @heretoinfinity:不;Python使用垃圾回收来释放无法访问的对象 (2认同)
  • 但当然,我想你仍然可以称其为“声明”,它完全没有必要(它的存在只是为了第三方工具的利益)。 (2认同)

det*_*tly 21

没有必要在Python中声明新变量.如果我们在谈论函数或模块中的变量,则不需要声明.只需为您需要的名称指定一个值:mymagic = "Magic".Python中的变量可以包含任何类型的值,但您不能限制它.

您的问题特别询问了类,对象和实例变量.创建实例变量的惯用方法是在__init__方法中而不是其他地方 - 虽然您可以在其他方法中创建新的实例变量,或者甚至在不相关的代码中,但这只是一个坏主意.它会使你的代码难以推理或维护.

例如:

class Thing(object):

    def __init__(self, magic):
        self.magic = magic
Run Code Online (Sandbox Code Playgroud)

简单.现在这个类的实例有一个magic属性:

thingo = Thing("More magic")
# thingo.magic is now "More magic"
Run Code Online (Sandbox Code Playgroud)

在类的名称空间中创建变量本身会导致不同的行为.它在功能上有所不同,只有在您有特定原因时才应该这样做.例如:

class Thing(object):

    magic = "Magic"

    def __init__(self):
        pass
Run Code Online (Sandbox Code Playgroud)

现在尝试:

thingo = Thing()
Thing.magic = 1
# thingo.magic is now 1
Run Code Online (Sandbox Code Playgroud)

要么:

class Thing(object):

    magic = ["More", "magic"]

    def __init__(self):
        pass

thing1 = Thing()
thing2 = Thing()
thing1.magic.append("here")
# thing1.magic AND thing2.magic is now ["More", "magic", "here"]
Run Code Online (Sandbox Code Playgroud)

这是因为类本身的名称空间与从其创建的对象的名称空间不同.我会留给你研究一下.

带回家的消息是,惯用的Python是(a)初始化__init__方法中的对象属性,(b)根据需要记录类的行为.你不需要为你所写的所有东西都找到完整的Sphinx级文档的麻烦,但至少有一些关于你或其他人可能需要提取它的细节的评论.


O. *_*sti 12

这可能晚了6年,但在Python 3.5及更高版本中,您声明了一个如下变量类型:

variable_name: type_name
Run Code Online (Sandbox Code Playgroud)

或这个:

variable_name # type: shinyType
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下(如果你CustomObject定义了一个类),你可以这样做:

customObj: CustomObject
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅那些.

  • 但这不是传统意义上的声明,而是一个提示,静态类型检查器和 IDE 可能会指出,但仍然会运行并失败。 (2认同)
  • 我的意思是,如果你执行 `a: int` 然后执行 `a='hello, world!'` 它不会失败,所以它不会声明 a 是一个 int,而只是一个 int。我应该说“它不会失败”,我的错。如果您执行了 `a: int`、`a='hello, world!'`、`a=a+1` ,那么在静态类型语言中编译时应该会失败。 (2认同)

小智 10

为了确定范围,我使用 -

custom_object =无