Python:如何从导入的模块调用类方法?

Python: How to call class method from imported module? “Self” argument issue

我有两个文件。我知道如何调用函数,但无法理解如何正确地从导入的模块调用方法,该模块的第一个参数是"self"。

我得到这个错误:

TypeError: prepare() missing 1 required positional argument: 'url'

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
cinemas.py    

import requests
from lxml.html import fromstring

class cinemas_info():

    def __init__(self, url):
        self.basic_cinemas_info(url)

    def prepare(self, url):


        url = requests.get(url)
        tree = fromstring(url.text)
        tree.make_links_absolute(url.url)
        return tree

    def basic_cinemas_info(self, url):


        tree = self.prepare(url)

        for city in tree.xpath(".//div[@class='city-caption']"):
            city1 = city.xpath("text()")[0]
            for cinema in city.xpath("following-sibling::*[1]/li/a"):
                name1 = cinema.xpath("text()")[0]
                detailed_url = cinema.xpath("@href")[0]
                print (city1.strip(), name1.strip(), ':')
                self.detailed_cinemas_info(detailed_url)
                self.detailed_cinemas_films(detailed_url)

    def detailed_cinemas_info(self, url):


        tree = self.prepare(url)

        for street in tree.xpath(".//div[@class='address']"):
            street1 = street.xpath("text()")[0]
            for phone in tree.xpath(".//div[@class='phone']"):
                phone1 = phone.xpath("text()")[0]
                for website in tree.xpath(".//div[@class='website']/a"):
                    website1 = website.xpath("@href")[0]
                    print ('\t', street1.strip(), phone1.strip(), website1.strip())

    def detailed_cinemas_films(self, url):


        showtimes_tab_url = '/showtimes/#!=&cinema-section=%2Fshowtimes%2F'
        tree = self.prepare(url + showtimes_tab_url)

        for film in tree.xpath('//div[@class="content"]'):
            film_name = film.xpath('.//a[@class="navi"]/text()')[0]
            for dates in film.xpath('.//li[contains(@class,"showtimes-day sdt")]'):
                film_dates = dates.xpath('.//div[@class="date"]/text()')[0]
                for times in dates.xpath('.//ul[@class="showtimes-day-block"]/li'):
                    film_times = times.xpath('a/text()')

                    if len(film_times) == 0:
                        film_times = None

                    is_3d = times.find('span')
                    if film_times is not None:
                        if is_3d is not None:
                            print(film_dates, film_name, film_times[0], '3D')
                        else:
                            print(film_dates, film_name, film_times[0])

if __name__ =="__main__":
    cinemas_info('http://vkino.com.ua/cinema/#!=')

.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#films.py

import requests
from cinemas import cinemas_info

def films_list():
    url = 'http://vkino.com.ua/afisha#!='
    tree = cinemas_info.prepare(url) #  <<<----Here is my call

    for films in tree.xpath('//*[@id="content"]/div/div[1]/ul[2]/li'):
        film_name = films.xpath('.//div[@class="title"]/a/text()')[0]
        film_url = films.xpath('.//div[@class="title"]/a/@href')[0]
        print(film_name, film_url)

if __name__ =="__main__":
    films_list()

我知道我可以将"def prepare"移出类并删除"self"参数,但是我想知道,在类内调用"def prepare"的正确方法是什么。


1
from cinemas import cinemas_info

您将在此处导入类定义。下一行:

1
cinemas_info.prepare(url)

您在这个类定义上调用prepare。您需要先实例化类,然后在类的实例上调用prepare()

1
2
ci = cinemas_info(url)
ci.prepare(url)  # this works

编辑:当您在一个实例上调用一个方法时,self变量会被python自动填充,作为对对象实例的引用,因此您只需要向def prepare(self, url)传递一个参数。


由于prepare的定义中含有self,您可以在cinemas_info的实例上调用此方法,也可以通过将该实例和url传递给prepare()来调用此方法。

所以您只需要创建一个cinemas_info类的实例,而python本身会将该实例传递给prepare()。你只要通过url

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#films.py

import requests
from cinemas import cinemas_info

def films_list():
    url = 'http://vkino.com.ua/afisha#!='
    c_info = cinemas_info(url) # created an instance of cinemas_info
    tree = c_info.prepare(url) # can now call prepare() on this instance

    for films in tree.xpath('//*[@id="content"]/div/div[1]/ul[2]/li'):
        film_name = films.xpath('.//div[@class="title"]/a/text()')[0]
        film_url = films.xpath('.//div[@class="title"]/a/@href')[0]
        print(film_name, film_url)

if __name__ =="__main__":
    films_list()