Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript到Python-了解类、方法和属性如何工作_Python_Python 2.7_Inheritance_Methods_Scrapy - Fatal编程技术网

Javascript到Python-了解类、方法和属性如何工作

Javascript到Python-了解类、方法和属性如何工作,python,python-2.7,inheritance,methods,scrapy,Python,Python 2.7,Inheritance,Methods,Scrapy,在Javascript中,有多种方法允许继承方法。 下面是使用几种方法的混合示例: A = { name: 'first', wiggle: function() { return this.name + " is wiggling" }, shake: function() { return this.name + " is shaking" } } B = Object.create(A) B.name = 'second' B.bop = function() {

在Javascript中,有多种方法允许继承方法。 下面是使用几种方法的混合示例:

A = {
    name: 'first',
    wiggle: function() { return this.name + " is wiggling" },
    shake: function() { return this.name + " is shaking" }
}

B = Object.create(A)
B.name = 'second'
B.bop = function() { return this.name + ' is bopping' }


C = function(name) {
    obj = Object.create(B)
    obj.name = name
    obj.crunk = function() { return this.name + ' is crunking'}

    return obj
}

final = new C('third')
这为我提供了以下继承层次结构

需要注意的重要事项之一是每个对象的
name
属性。当运行一个方法时,即使是在原型链的最底层,由
this
关键字定义的本地上下文也会确保使用localmost属性/变量

我最近转向了Python,但我在理解子类如何访问超类方法以及变量作用域/对象属性如何工作方面遇到了困难

我在Scrapy中创建了一个Spider,它(相当成功)在一个域中抓取了2000多个页面,并将它们解析为我需要的格式。很多助手只在主
parse\u response
方法中起作用,我可以直接在数据上使用这些方法。最初的蜘蛛看起来像这样:

from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from spider_scrape.items import SpiderItems

class ScrapeSpider(CrawlSpider):

    name              =   "myspider"
    allowed_domains   =   ["domain.com.au"]
    start_urls        =   ['https://www.domain.com.au/']
    rules             =   (Rule(SgmlLinkExtractor(allow=()), 
                                                  callback="parse_items", 
                                                  follow=True), )

    def parse_items(self, response):
        ...
回调函数parse_items包含为我处理响应的逻辑。当我概括所有内容时,我最终得出以下结论(打算在多个域上使用此方法):

当我通过Scrapy命令行运行此命令时,控制台中出现以下错误:

经过一些测试后,将列表理解更改为该选项后,它可以工作:
用于self中的域。允许的域:

很好,这似乎与Javascript中的
this
关键字非常相似-我正在使用对象的属性来获取值。还有许多变量/属性将保存scrape所需的XPath表达式:

class DomainSpider(BaseSpider):

    name = 'Domain'
    page_title      =      '//title'
    page_content    =      '//div[@class="main-content"]'
将Spider的其他部分更改为模仿allowed_domains变量,我收到了以下错误:

我尝试了几种不同的方法来设置属性,包括使用
self.page\u content
和/或
\uuuuuu init\uuuuuuuuu(self)
构造函数,但没有成功,只是出现了不同的错误

我完全不知道这里发生了什么。我期望发生的行为是:

  • 当我从终端运行
    scrapy crawl
    时,它实例化了DomainSpider类
  • 该类中的任何类常量都可用于其继承的所有方法,类似于Javascript及其
    this
    关键字
  • 由于上下文关系,将忽略其超类中的任何类常量
  • 如果有人能

    • 给我解释一下上面的内容
    • 给我指出一些比LPTHW更丰富的东西,但不是使用Python的TDD,这将是令人惊讶的

    提前感谢。

    我不熟悉JavaScript,但与您类似的问题总是会有一个答案,建议您必须学习使用Python的方法,不要试图强迫Python与其他语言类似。试图用Python重新创建Javascript风格,我想到了以下方法:

    class A(object):
        def __init__(self):
            self.name = 'first'
        def wiggle(self):
            return self.name + ' is wiggling'
        def shake(self):
            return self.name + ' is shaking'
    
    创建
    A
    的实例,更改其名称并向该实例添加方法属性

    一种函数,返回
    A
    的实例,并带有附加属性
    crunk
    。我认为您的示例并非如此,
    thing
    将不会有
    bop
    方法,尽管函数中的另一个语句可以添加一个方法

    def c(name):
        thing = A()
        thing.name = name
        thing.crunk = lambda : thing.name + ' is crunking'
        return thing
    
    final = c('third')
    
    没有任何继承,只有带有附加属性的
    A
    的实例。您将得到以下结果:

    >>> 
    >>> b.name
    'second'
    >>> b.bop()
    'second is bopping'
    >>> b.shake()
    'second is shaking'
    >>> b.wiggle()
    'second is wiggling'
    >>> 
    >>> final.name
    'third'
    >>> final.crunk()
    'third is crunking'
    >>> final.shake()
    'third is shaking'
    >>> final.wiggle()
    'third is wiggling'
    >>> final.bop()
    
    Traceback (most recent call last):
      File "<pyshell#32>", line 1, in <module>
        final.bop()
    AttributeError: 'A' object has no attribute 'bop'
    >>> 
    
    Foo
    继承
    A
    的所有内容,并定义一个附加属性
    bop

    class Foo(A):
        def bop(self):
            return self.name + ' is bopping'
    
    Bar
    继承了
    Foo
    的所有内容,并定义了一个附加属性
    crunk

    class Bar(Foo):
        def crunk(self):
            return self.name + ' is crunking'
    
    Baz
    继承了
    Bar
    和overides
    wiggle

    class Baz(Bar):
        def wiggle(self):
            return 'This Baz instance, ' + self.name + ', is wiggling'
    
    foo = Foo('second')
    bar = Bar('third')
    baz = Baz('fourth')
    
    用法:

    >>> 
    >>> foo.name
    'second'
    >>> foo.bop()
    'second is bopping'
    >>> foo.shake()
    'second is shaking'
    >>> foo.wiggle()
    'second is wiggling'
    >>> 
    >>> bar.name
    'third'
    >>> bar.bop()
    'third is bopping'
    >>> bar.shake()
    'third is shaking'
    >>> bar.wiggle()
    'third is wiggling'
    >>> bar.crunk()
    'third is crunking'
    >>> 
    >>> baz.wiggle()
    'This Baz instance, fourth, is wiggling'
    >>>
    
    这些示例中的类具有仅对类的实例有效的方法属性-方法需要绑定到实例。我没有包括任何不需要绑定到实例的类方法或静态方法的示例,这有一些很好的答案

    摆动 >>>A.摇摆 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 A.摇摆 TypeError:必须以实例作为第一个参数调用unbound方法wiggle()(没有得到任何结果) >>>巴·克鲁克 >>>Bar.crunk() 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 Bar.crunk() TypeError:必须使用Bar实例作为第一个参数调用未绑定的方法crunk()(但没有得到任何结果) >>>
    Python不是JavaScript。你读完教程了吗?我想pyvideo.org上的一些视频可能会有一些启发,如果您试图理解Python中属性是如何工作的,我建议您从使用“toy”类的简单示例开始,而不是使用Scrapy作为示例。一旦你理解了这些概念,你就可以轻松地处理Scrapy正在做的事情了。通过谷歌搜索“Python类和实例变量/属性”,你可以在这里和网页上找到一些其他问题,如。
    class Bar(Foo):
        def crunk(self):
            return self.name + ' is crunking'
    
    class Baz(Bar):
        def wiggle(self):
            return 'This Baz instance, ' + self.name + ', is wiggling'
    
    foo = Foo('second')
    bar = Bar('third')
    baz = Baz('fourth')
    
    >>> 
    >>> foo.name
    'second'
    >>> foo.bop()
    'second is bopping'
    >>> foo.shake()
    'second is shaking'
    >>> foo.wiggle()
    'second is wiggling'
    >>> 
    >>> bar.name
    'third'
    >>> bar.bop()
    'third is bopping'
    >>> bar.shake()
    'third is shaking'
    >>> bar.wiggle()
    'third is wiggling'
    >>> bar.crunk()
    'third is crunking'
    >>> 
    >>> baz.wiggle()
    'This Baz instance, fourth, is wiggling'
    >>>
    
    >>> A.wiggle
    <unbound method A.wiggle>
    >>> A.wiggle()
    
    Traceback (most recent call last):
      File "<pyshell#41>", line 1, in <module>
        A.wiggle()
    TypeError: unbound method wiggle() must be called with A instance as first argument (got nothing instead)
    >>> Bar.crunk
    <unbound method Bar.crunk>
    >>> Bar.crunk()
    
    Traceback (most recent call last):
      File "<pyshell#43>", line 1, in <module>
        Bar.crunk()
    TypeError: unbound method crunk() must be called with Bar instance as first argument (got nothing instead)
    >>>