Python Web 2 —— 类和函数的声明和调用

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://linsh-tech.blog.csdn.net/article/details/51679096

        我们知道python其实也是面向对象的语言,既然提到了面向对象编程(OOP),那我们理所应当地会想到类和函数的概念,那么我们接下来就看看在python中类和函数是如何声明和调用的。


一、python中的类:

1.类的定义:

class Test(father_class):
    pass

        如上述代码,在python中声明一个类通过class关键词,class后面的Test就是此类的类名,类名之后的(father_class)用来说明当前类继承了哪个父类,假如没有父类,则继承自(object)类

2.类的实例化,对象的创建:

    t = Test()

3.类的__init__方法:

        由于类起到模板的作用,所以,可以在创建实例的时候,把一些必要的属性强制填写进去,与我们在java的类的构造函数中所作的操作相似。这时候我们需要通过定义一个特殊的__init__方法,例如在创建的时候把name属性绑上去:

class Test(object):
   	def __init__(self,name):
   	    self.name = name

        注意:__init__的第一个参数永远是self,表示的是实例本身,所以在此方法中把属性绑定到self上即可。但是,假如__init__方法之后,创建实例时,就不能像上述中那样传入空的参数了,必须根据__init__方法的参数格式匹配参数,但是self是不需要传入的,Python解释器自己会把实例变量传进去:

>>>t = Test('linsh')
>>>print(t.name)
linsh


4.类的类方法:

class person(object):
    def setName(self,name):
        self.name = name
    def getName(self):
        return self.name

        如上述代码所示,类方法的第一个参数也必须是self,其他和普通方法一样,调用的时候,只需要在实例变量上直接调用,除了self不用传递,其他参数正常传入:

p = person()
p.setName('lin')
name  = p.getName()

print(name)


5.类的私有变量:

        在java中,我们可以通过public、private或者protect等关键字来修饰方法和变量,其作用就是设置方法和变量的访问权限。在python中也要类似的做法,例如我们希望把name属性设置为私有的,即外部不能直接通过实例对象访问此属性,而应通过开放的接口来获取该属性,例如:

class person(object):
    def setName(self,name):
        self.__name = name
    def getName(self):
        return self.__name
        如上述所示,在属性name前面加上双下划线“__”即可将属性设置为私有,那么外部就不能直接通过 实例对象.name来访问该属性了,而应通过该类的类方法getName()来访问此属性,否则会报错。


二、python中的函数:

        在python中,我们通过def关键词来声明一个方法,例如:

def hello():             #无参函数
    print('Hello!')

def hello(name):  #带参函数
    print('Hello,',name)

def getStr(firstName,lastName): #有返回
    return lastName+firstName

        上面的函数与其他高级语言基本相似,除此之外,python定义的函数还可以同时返回多个数据

import math

def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny

        调用此函数的时候,按顺序接收函数返回数据:

>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632 70.0

        原来返回值是一个tuple!但是,在语法上,返回一个tuple可以省略括号,而多个变量可以同时接收一个tuple,按位置赋给对应的值,所以,Python的函数返回多值其实就是返回一个tuple,但写起来更方便。


三、函数类型:

函数的类型除了根据是否有返回值来划分之外,还可以根据带参情况来进行划分,划分为:必选参数、默认参数、可变参数、关键字参数和命名关键字参数

1.必选参数:

必选参数函数就是调用函数时传入函数中的实参数量和顺序必须与函数声明时完全一致,否则会报错:

def power(x, n):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

        调用如下,参数不一致时出现了报错,因为有参数缺失:

>>> power(5, 2)
25
>>> power(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: power() missing 1 required positional argument: 'n'

2.默认参数:

def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s

        如上述代码所示,在声明power函数时,对第二个参数n设置了默认值,则在调用此函数时,可以有两种方式:一是传入两个参数的power(5,2);另一个是只传入一个参数power(5),此时第二个参数n会使用默认值,所以不会报错:

>>> power(5)
25
>>> power(5, 2)
25


3.可变参数:

顾名思义,可变参数的意思就是定义的函数传入参数可以是0个、1个...甚至无数个。对于需要传入多个参数,且参数数量不确定的函数,我们会想到将输入参数声明为一个list或者tuple,例如:

def calc(numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

        调用时,传入一个list或者tuple:

>>> calc([1, 2, 3])
14
>>> calc((1, 3, 5, 7))
84

        但是,可变参数函数的调用,应该简化为一下形式:

>>> calc(1, 2, 3)
14
>>> calc(1, 3, 5, 7)
84

        那么,如何将list或者tuple函数改写成可变参数函数呢,其实很简单,只需在输入参数前面加上一个“*”号即可:

def calc(*numbers):
    sum = 0
    for n in numbers:
        sum = sum + n * n
    return sum

        如果已有一个list或者tuple,要将其传入可变参数函数中,有两种方式,显然第二种更为方便,Python允许你在list或tuple前面加一个*号,把list或tuple的元素变成可变参数传进去

>>> nums = [1, 2, 3]
>>> calc(nums[0], nums[1], nums[2])
14
>>> calc(*nums)
14


4.关键字参数:

可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple。而关键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)

        上述函数声明中,name和age都是必须参数,而kw就是关键字参数,调用时必须参数必须有实参输入,而关键字参数可以无输入:

>>> person('Michael', 30)
name: Michael age: 30 other: {}

        添加任意关键字参数的形式,相当于一种key-value的形式,因为关键字参数最后会被保存成一个dict字典:

>>> person('Bob', 35, city='Beijing')
name: Bob age: 35 other: {'city': 'Beijing'}
>>> person('Adam', 45, gender='M', job='Engineer')
name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

        类似可变参传入list和tuple作为输入的形式,我们也可以将一个已有的dict作为输入参数传入关键字参数函数中:

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

**extra表示把extra这个dict的所有key-value用关键字参数传入到函数的**kw参数,kw将获得一个dict,注意kw获得的dict是extra的一份拷贝,对kw的改动不会影响到函数外的extra


5.命名关键字参数:
假如只想接收关键字参数中的部分数据,我们可以通过条件语句进行筛选,如下只接收city和job关键字的数据:

def person(name, age, **kw):
    if 'city' in kw:
        # 有city参数
        pass
    if 'job' in kw:
        # 有job参数
        pass
    print('name:', name, 'age:', age, 'other:', kw)

        但是,调用函数时仍然可以传入不受限制的关键字参数:

>>> person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)

        为了限制关键字参数,我们可以使用命名关键字参数,改写person函数如下:

def person(name, age, *, city, job):
    print(name, age, city, job)

和关键字参数**kw不同,命名关键字参数需要一个特殊分隔符**后面的参数被视为命名关键字参数。调用的方式如下:

>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

如果函数定义中已经有了一个可变参数,后面跟着的命名关键字参数就不再需要一个特殊分隔符*

def person(name, age, *args, city, job):
    print(name, age, args, city, job)

        命名关键字参数调用时,必须传入参数名,否则会报错:

>>> person('Jack', 24, 'Beijing', 'Engineer')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: person() takes 2 positional arguments but 4 were given

命名关键字参数可以有缺省值,从而简化调用:

def person(name, age, *, city='Beijing', job):
    print(name, age, city, job)

        上面函数调用时,由于city参数已有默认值,所以可以不传入该参数:

>>> person('Jack', 24, job='Engineer')
Jack 24 Beijing Engineer

6.参数组合:

在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。但是请注意,参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数

def f1(a, b, c=0, *args, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)

def f2(a, b, c=0, *, d, **kw):
    print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)

        调用方式如下,解释器自动按参数名和参数位置将各种参数传入到对应参数中:

>>> f1(1, 2)
a = 1 b = 2 c = 0 args = () kw = {}
>>> f1(1, 2, c=3)
a = 1 b = 2 c = 3 args = () kw = {}
>>> f1(1, 2, 3, 'a', 'b')
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
>>> f1(1, 2, 3, 'a', 'b', x=99)
a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
>>> f2(1, 2, d=99, ext=None)
a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}


四、包含类函数的类声明:

代码:

class person(object):
    def setName(self,name):
        self.name = name
    def getName(self):
        return self.name

调用方式:

p = person()
p.setName('lin')
name  = p.getName()

展开阅读全文

python类中函数互相调用

09-25

写了一个算法来爬取一个网站中的新闻,定义一个类,初始函数 __init__(self)用来连接数据库;函数 main(self)用来爬取数据,其中main()内部再调用conn()和judge()函数,但是程序运行到main()函数调用conn()这一步时就出问题,提示问题'Connection' object is not callablern具体代码和问题如下:rn[code=python]import timernfrom selenium import webdriverrnimport pymysqlrnimport uuidrnrnrnclass mainAll(object):rnrn def __init__(self):rn self.conn = pymysql.connect(host='localhost', user='root', passwd='123', db='tianyan', port=3306, charset='utf8')rn self.cur = self.conn.cursor() # 获取一个游标rn self.main()rn self.cur.close()rn self.conn.close()rnrn def main(self):rn # 获取当前年月日rn y = time.strftime('%Y', time.localtime(time.time())) # 年rn m = time.strftime('%m', time.localtime(time.time())) # 月rn d = time.strftime('%d', time.localtime(time.time())) # 日rn data_time = time.strftime('%Y-%m-%d', time.localtime(time.time())) # 抓取时间rn data_time_now = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))rn website = '海丝商报'rnrn # 创建相应时间的url地址rn url = 'http://fjrb.fjsen.com/nasb/html/%s-%s/%s/node_122.htm' % (y, m, d)rn driver = webdriver.Chrome()rn driver.get(url)rn # 找到版面数rn sheets = driver.find_element_by_xpath("//table[@cellpadding='2']")rn sheets_len = len(sheets.find_elements_by_tag_name('tr'))rn # 找到每个版面的标题数量rnrn for sheet in range(sheets_len):rn titles = driver.find_element_by_xpath("//table[@cellpadding='1']")rn titles_len = int(len(titles.find_elements_by_tag_name('tr')) / 2)rn content_type = driver.find_element_by_xpath("//table[@cellpadding='2']").find_elements_by_tag_name('tr')rn content_type = content_type[sheet].text.split(':')[-1] # 以冒号为分隔符切开版面的文字rnrn # 点击版面的第一篇文章rn title_button = driver.find_element_by_xpath("//*[@id='demo']/table[1]/tbody/tr[3]/td[2]/table/tbody/"rn "tr[4]/td/table/tbody/tr/td[2]/table/tbody/tr[1]/td/table/"rn "tbody/tr[4]/td/div/table/tbody/tr[1]/td[2]/a")rn title_button.click()rnrn for title in range(titles_len):rnrn # 找到主标题和子标题的table表rn title_table = driver.find_element_by_xpath(rn "//*[@id='demo']/table/tbody/tr[3]/td[2]/table/tbody/tr[4]//tr")rnrn content_title = title_table.find_elements_by_tag_name('p')[0].textrn content_subtitle = title_table.find_elements_by_tag_name('p')[1].textrn content = driver.find_element_by_xpath("//table[@class='content_tt']").textrn # 获取左下角每一版的所有标题的链接rn content_id = driver.find_elements_by_xpath("//*[@id='demo']/table/tbody/tr[3]/td[1]/table/tbody/tr[3]/"rn "td/table//a")rn content_id = content_id[title].get_attribute('href')rn content_id = content_id.split('content_')[-1].split('.')[0] # 正则表达式没有处理成功!!!!!rn # content_id = driver.current_urlrn # 'http://fjrb.fjsen.com/nasb/html/2017-09/21/content_1055929.htm?div=-1'rn idd = str(uuid.uuid1())rn idd.replace('-', '')rn # 新闻时间和爬取时间是一个时候 sentiment_source 和sentiment_website是同一处理的rn lists = (idd, content_title, content_subtitle, website, data_time, url, website, data_time_now, content,rn content_id, content_type)rn self.conn(lists)rn driver.find_elements_by_xpath("//a[@class='preart']")[-1].click() # 点击下一篇章rn # 当把一版的所有标题都走完以后,点击下一版,回到外层循环的页面rn if title == titles_len - 1 and sheet == 0:rn driver.find_elements_by_xpath("//a[@class='preart']")[0].click()rn elif title == titles_len - 1:rn driver.find_elements_by_xpath("//a[@class='preart']")[1].click()rn elif title == 0 and sheet == 0:rn flag = self.judge(content_id)rn if flag > 0:rn breakrn # 我这里的break会不会让定时程序都停止了rn driver.close()rnrn def conn(self, table):rn # 名称 职位 公司名称 entuidrn sql = "INSERT INTO sentiment_info (sentiment_id, sentiment_title, sentiment_subtitle, sentiment_source," \rn "sentiment_time, sentiment_url,sentiment_website,sentiment_create_time,sentiment_content," \rn "sentiment_source_id,sentiment_type) VALUES ( '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s'," \rn " '%s','%s')"rn self.cur.execute(sql % table)rn self.conn.commit()rnrn # 第一页点击 driver.find_element_by_xpath("//a[@class='preart']").click() 即可到下一页rnrn def judge(self, content_id):rn sql = "SELECT COUNT(*) FROM sentiment_info WHERE sentiment_source='海丝商报' AND sentiment_type='要闻'" \rn " AND sentiment_source_id=%s", content_idrn self.cur.execute(sql)rn a = self.cur.fetchall()rn a = max(max(a))rn self.conn.commit()rn return arnrnif __name__ == '__main__':rn mainAll()[/code]rnrn问题显示:rn[code=python]C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe "D:\pycharm\PyCharm 2016.3\helpers\pydev\pydevd.py" --multiproc --qt-support --client 127.0.0.1 --port 53782 --file D:/pyworkpeace/HaiSirnwarning: Debugger speedups using cython not found. Run '"C:\Users\Administrator\AppData\Local\Programs\Python\Python36\python.exe" "D:\pycharm\PyCharm 2016.3\helpers\pydev\setup_cython.py" build_ext --inplace' to build.rnpydev debugger: process 7620 is connectingrnrnConnected to pydev debugger (build 163.8233.8)rnTraceback (most recent call last):rn File "D:\pycharm\PyCharm 2016.3\helpers\pydev\pydevd.py", line 1596, in rn globals = debugger.run(setup['file'], None, None, is_module)rn File "D:\pycharm\PyCharm 2016.3\helpers\pydev\pydevd.py", line 974, in runrn pydev_imports.execfile(file, globals, locals) # execute the scriptrn File "D:\pycharm\PyCharm 2016.3\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfilern exec(compile(contents+"\n", file, 'exec'), glob, loc)rn File "D:/pyworkpeace/HaiSi", line 110, in rn mainAll()rn File "D:/pyworkpeace/HaiSi", line 20, in __init__rn self.main()rn File "D:/pyworkpeace/HaiSi", line 75, in mainrn self.conn(lists)rnTypeError: 'Connection' object is not callablernrnProcess finished with exit code 1rn[/code] 论坛

没有更多推荐了,返回首页