使用dir可以查看标识符所包含的方法列表
def method1():
print("hello world")
# dir查看该标识符包含的方法列表
print(dir(method1))
结果
['__annotations__', '__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__get__', '__getattribute__', '__globals__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__', '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__', '__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
1、定义类
# 定义类
class Cat:
name = "tom"
def eat(self):
print(self.name + " eat")
def run(self):
print(self.name + " run")
cat = Cat()
cat.eat()
cat.run()
# 查看该对象的内存地址
print(id(cat))
结果
tom eat
tom run
2542136215296
2、私有化属性
在java中使用private关键字可以将属性或者方法定义为私有,在python中并没有这么直接的方式。默认在标识符前面加两个下划线来将其表示为私有,其实还是可以访问到(如下代码:使用_类型__方法名),有时也可以使用一个下划线来定义。
# 私有化,python并没有提供直接的私有化支持,但是可以在
# 标识符前加两个下划线让其成为私有的,此时调用会报错,因为python会将该方法名称变为 _类型__方法名()
# 所以非要调用该私有方法其实也是可以的,但是要求不这样做
class Dog:
name = "tony"
def __eat(self):
print(self.name + " eat")
def _run(self):
print(self.name + "run")
dog = Dog()
# 会报错
# dog.__eat()
# 能访问到
dog._Dog__eat()
# 也可以使用一个下划线,但是调用时不会报错,只是python不会修改其名称了,相当于是一种约定,该方法或属性为私有
dog._run()
结果
tony eat
tony run
3、类属性
和java差不多,下面代码的number从属于Cow类,当实例化的类调用方法修改该变量时,其他实例访问该变量时值也会发生变化。但是如果使用实例名.变量名直接修改,将会在该实例的命名空间创建一个局部变量,此时即使该实例修改了number值,其他实例的number值还是没有改变。
# 类属性
class Cow:
number = 1
def init(self):
Cow.number += 1
cow1 = Cow()
cow1.init()
print("cow1时数量:", cow1.number)
cow2 = Cow()
cow2.init()
print("cow2时数量:", cow2.number)
# 此处相当于cow1的局部变量
cow1.number = 5
print("cow1时数量:", cow1.number)
print("cow2时数量:", cow2.number)
结果
cow1时数量: 2
cow2时数量: 3
cow1时数量: 5
cow2时数量: 3
4、继承
python的继承,在定义类的括号中写入父类的名称即可,python支持多继承,即可以继承多个父类,继承后可以对方法进行重写。同时使用issubclass可以判断某个类是否是另一个类的子类,使用类型.__bases__可查看该类的所有基类(所有类最终的基类为Object),isinstance可以查看是否为某个类的实例,实例.__class__可查看该实例所属的类,使用type也可以查看。hasattr可查看是否拥有某个属性,callable查看某个属性是否可调用。
# 继承
class Filter():
def init(self):
self.blocked = []
def filter(self, sequence):
print([x for x in sequence if x not in self.blocked])
class HelloFilter(Filter):
def init(self):
self.blocked = ["hello"]
class WorldFilter(Filter):
def init(self):
self.blocked = ["world"]
helloFilter = HelloFilter()
helloFilter.init()
helloFilter.filter(["hello", "world", "java", "hello", "world", "python"])
worldFilter = WorldFilter()
worldFilter.init()
worldFilter.filter(["hello", "world", "java", "hello", "world", "python"])
print("HelloFilter类是Filter类的子类:", issubclass(HelloFilter, Filter))
print("HelloFilter的基类为:", HelloFilter.__bases__)
print("Filter的基类为:", Filter.__bases__)
print("helloFilter的是否为HelloFilter的实例:", isinstance(helloFilter, HelloFilter))
print("helloFilter的是否为Filter的实例:", isinstance(helloFilter, Filter))
print("helloFilter的是否为WorldFilter的实例:", isinstance(helloFilter, WorldFilter))
print("helloFilter所属类为:", helloFilter.__class__)
# 对于python2.x type函数返回为instance
print("helloFilter所属类为:", type(helloFilter))
print("helloFilter包含的属性:", hasattr(helloFilter, "blocked"))
print("helloFilter的属性blocked是否可调用:", callable(getattr(helloFilter, "blocked", None)))
print("helloFilter包含的属性:", hasattr(helloFilter, "init"))
print("helloFilter的属性init是否可调用:", callable(getattr(helloFilter, "init", None)))
结果
['world', 'java', 'world', 'python']
['hello', 'java', 'hello', 'python']
HelloFilter类是Filter类的子类: True
HelloFilter的基类为: (<class '__main__.Filter'>,)
Filter的基类为: (<class 'object'>,)
helloFilter的是否为HelloFilter的实例: True
helloFilter的是否为Filter的实例: True
helloFilter的是否为WorldFilter的实例: False
helloFilter所属类为: <class '__main__.HelloFilter'>
helloFilter所属类为: <class '__main__.HelloFilter'>
helloFilter包含的属性: True
helloFilter的属性blocked是否可调用: False
helloFilter包含的属性: True
helloFilter的属性init是否可调用: True
5、多重继承
python中一个类可以继承多个类,注意多个基类中拥有相同的方法时,继承列表中排在前面的基类中的方法会对排在后面的方法进行覆盖,如下代码所示
# 多继承
class Human():
def eat(self):
print(self.name + ": eat")
def method(self):
print("Human method")
class Sing():
def sing(self):
print(self.name + ": sing")
def method(self):
print("Sing method")
# Human中的method方法会覆盖Sing中的method方法
class Tom(Human, Sing):
def init(self):
self.name = "tom"
# Sing中的method方法会覆盖Human中的method方法
class Tony(Sing, Human):
def init(self):
self.name = "tony"
tom = Tom()
tom.init()
tom.eat()
tom.sing()
tom.method()
tony = Tony()
tony.method()
结果
tom: eat
tom: sing
Human method
Sing method
6、使用abc模块实现抽象基类
抽象类不能被实例化,抽象类必须被实现。抽象类的子类可以不对抽象类中的方法进行实现,此时该子类也是抽象类。
from abc import ABC, abstractmethod
# 抽象基类
class AbstractClass(ABC):
@abstractmethod
def method(self):
pass
class ImplementsClass(AbstractClass):
def method(self):
print("this is implement class")
# 不能对抽象类进行实例化
# abstractClass = AbstractClass()
implementsClass = ImplementsClass()
implementsClass.method()
结果
this is implement class