python面向对象遇见问题

参考:

python中的正则表达式: 点击打开链接

python中类(class)和实例(instance) 点击打开链接

Python 面向对象  点击打开链接
修改原文中的错误,调用Employee__count(),也需要加Employee类在前:
# -*- coding:utf-8 -*-
#!/C:/Users/C/Desktop/
class Employee:
    'Employee表示类名'
    #b=Employee()
    #b即为一个Employee类的实例,可以任意地给实例绑定属性,如:b.name='Lora',print(b.name)='Lora'
    Employee_count=0
    def __init__(self,name,salary):
        #通过__init__方法把一些需要的属性强制填入,注意到__init__方法的第一个参数self,表示创建的实例本身,所以可以用self.属性传入
        self.name=name    #实现把属性绑定在class Employee上
        self.salary=salary
        Employee.Employee_count+=1
    def displayCount(self):
        print("Total Employee %d" %Employee.Employee_count)
    def displayEmplyee(self):
        print("Name:",self.name,"Salary:",self.salary)
pl1=Employee("Maya",10000)
pl2=Employee("Lora",20000)
pl3=Employee("Alice",30000)
pl1.displayEmplyee()
pl2.displayEmplyee()
print(Employee.Employee_count)#在菜鸟教程用的是Employee_count,lack the Class Employee

    在定义的方法(即class下的函数)中默认带了___init__中的属性,可以直接通过self.attribute引用。

1.访问属性:

class name:
    '名字,first name,last name'
    def __init__(self,x,y):
        self.x=x
        self.y=y
getattr(classname,attr)#访问属性
a=name('Bob','Smith')
b=name('Zhou','Fang')
print(getattr(a,'x')#访问属性,若无返回NameError:name'x' is undefined
setattr(a,'age',8)#如果存在属性age,把属性值8赋给‘age'如果不存在'age',创建这个属性,并把值赋给他
>>> hasattr(ex1,'name')#有无属性,返回True或False
False
>>> delattr(ex1,'age')#delete attribute
>>> getattr(ex1,'age')
Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    getattr(ex1,'age')
AttributeError: 'name' object has no attribute 'age'

2.类的私有属性:

在定义类的私有属性时需要在定义的属性前加'__',私有属性(private attr)只能在类内可以调用,类外不能调用,实例(instance)不能调用。公有属性(public attr)则都可以调用。如:

class Count():
    __sCount=0  # private attr
    pCount=0  # public attr
    def count(self):
        self.__sCount+=1
        self.pCount+=1
        print('私人',self.__sCount)
c=Count()  #c为Count类实例
c.count()
c.count()
print('pCount:',c.pCount)
print('sCount:',c.__sCount)  # 没法调用
# 输出
私人 1
私人 2
pCount: 2
Traceback (most recent call last):
  File "C:\Users\C\Desktop\pr\Third_Example.py", line 25, in <module>
    print('sCount:',c.__sCount)
AttributeError: 'Count' object has no attribute '__sCount'

3.正则表达式:

常用函数:

re.match()

re.search()

re.compile()

re.match(pattern,str,flags=0)函数:

   pattern 表示要匹配的正则表达式,str是匹配的字符串,flags是标志位,表示匹配方式。

    pattern可以是字符串,也可以是一些符号组成的表达式。如:

import re
a=re.match('hell','hello world')
print(a)
-> <_sre.SRE_Match object; span=(0, 4), match='hell'>
b=re.match(r'\D{4}','hello World',re.I) #r'\D{4}',表示重复匹配非数字4次,既然没有指明开头位置那就从0开始,走四次
print(b)
print(re.match(r'[hel]+','Hello World',re.I))  #匹配字符从'h','e','l'中选取匹配

两者同一作用。

    与其说匹配多个表达式,不如说是匹配多少次(菜鸟教程中对于正则表达式中字符用重复次数的问题)


但是有个点没太看懂:

#!/usr/bin/python
import re
 
line = "Cats are smarter than dogs"
 
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)  # r'(.*) are (.*?) .*'  这个语句是什么意思,它所表达的pattern是什么
 # pattern表示:分组1 are 分组2.分组1匹配同行中除换行符,匹配次数0到多次,同理分组2,re.I忽略大小写,re.M多行处理
if matchObj:
   print "matchObj.group() : ", matchObj.group()  # 返回匹配的字符串
   print "matchObj.group(1) : ", matchObj.group(1)
   print "matchObj.group(2) : ", matchObj.group(2)
   print("matchObj.groups()",matchObj.groups)  # 返回匹配的元组
else:
   print "No match!!"
r'(.*) are (.*?) .*'
解析:
首先,这是一个字符串,前面的一个 r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 
r可有可无。
 (.*) 第一个匹配分组,.* 代表匹配除换行符之外的所有字符。
 (.*?) 第二个匹配分组,.*? 后面多个问号,代表非贪婪模式,也就是说只匹配符合条件的最少字符
 后面的一个 .* 没有括号包围,所以不是分组,匹配效果和第一个一样,但是不计入匹配结果中。
matchObj.group() 等同于 matchObj.group(0),表示匹配到的完整文本字符
matchObj.group(1) 得到第一组匹配结果,也就是(.*)匹配到的
matchObj.group(2) 得到第二组匹配结果,也就是(.*?)匹配到的
因为只有匹配结果中只有两组,所以如果填 3 时会报错。-->分组1 are 分组2 匹配匹配字符串中对于字符

我找到字符串的介绍,发现关于输出无符号数有一个用法:

u'hello world' ->'hello world'

>>> a=r'(.*) are (.*?) .*'
>>> type(a)
<class 'str'>
>>> print(u'(.*) are (.*?) .*')
(.*) are (.*?) .*
>>> b=u'(.*) are (.*?) .*'
>>> type(b)
<class 'str'>
>>> if a==b:
	print('True')
else:
	print("False")

True  # 说明r 与 u 的用法同
 # r 表示字符串为非转义的原始字符串,让编译器忽略反斜杠,也就是忽略转义字符。但是这个字符串里没有反斜杠,所以这个 r 可有可无。
#这里需要强调一下反斜杠\的作用:
反斜杠后边跟元字符去除特殊功能;(即将特殊字符转义成普通字符)
反斜杠后边跟普通字符实现特殊功能;(即预定义字符)
引用序号对应的字组所匹配的字符串。

还注意到span()函数:

s="china is more harder than glass"
a=re.search('than',s)
print(a)  # -> <_sre.SRE_Match object; span=(18, 22), match='than'>
a.span()  #  ->(18,22) 

span()返回范围。

同类型的例子:

m=re.search(r'(\d{3})-(\d{3})-(\d{4})','hkdhkjshkjhdjhdj jgkdj jgls 010-230-3224')
print(m)
-> <_sre.SRE_Match object; span=(28, 40), match='010-230-3224'>

    匹配正则表达式是分别匹配3次数字,3次数字,4次数字,中间用'-'连接,可以看出满足条件的是010-230-3224.

    用m.group(num).可以得到三个分组:

print(m.group())
print(m.group(1))
print(m.group(2))
->010
->230
->3224

groups()返回多个值的元组,可以使用多重赋值的技巧,进行赋值

>>> import re
>>> m=re.search(r'(\d{3})-(\d{3}-\d{4})','My phone number is 012-239-4597')
>>> area_code,main_code = m.groups()
>>> print(area_code)
012
>>> print(main_code)
239-4597
>>>

3.1re.compile(pattern,flags=0)和直接调用re.match(pattern,string,flags),re.search(pattern,string,flags)的关系:

pt=re.compile(r'\d+',re.I)  # 更习惯
m=pt.match('A234B68 3479C')
print(m)

# equal to 
m=re.match(r'\d','A234B68 3479C',re.I)
print(m)
re.match()表示从字符串首字符开始匹配,而re.search()不一定从首字符开始。







猜你喜欢

转载自blog.csdn.net/augustmoore/article/details/80748495